Setting Up Deploy Previews on Netlify for Every Pull Request
A Deploy Preview is the real, fully built site for a pull request, served at its own URL before the change ever reaches production. Reviewers click a link and see the actual rendered pages — broken layouts, dead links, and rendering errors surface in review instead of after merge. On Netlify this is mostly automatic once the repo is connected; the work is in scoping environment variables correctly and knowing how the URL and PR comment behave. This guide covers the full setup. It sits under Netlify vs Vercel Deployment Strategies within Production-Ready Deployment & CI/CD Workflows.
Prerequisites
- A site already deploying to Netlify through its Git integration (not manual
netlify deploy). - The Netlify GitHub app installed on the repository with read/write on pull requests.
- A
netlify.tomlcommitted to the repo so build settings are version-controlled. - Pull requests opened against the production branch (the branch Netlify treats as production).
Confirming Deploy Previews Are On
Once a repo is linked via Git, Netlify enables Deploy Previews for pull requests by default. Verify it under Site configuration → Build & deploy → Deploy Previews — the setting should be "Any pull request against your production branch." If someone disabled it, flip it back. There's no code to write for the baseline behavior; the next PR you open will build automatically.
Pin the build settings in netlify.toml so they're reviewed in Git rather than living only in the dashboard:
[build]
command = "npm run build"
publish = "dist"
[build.environment]
NODE_VERSION = "20"
These apply to every context — production, branch deploys, and Deploy Previews — unless a context overrides them.
The Per-PR URL
Each pull request gets a deterministic URL:
https://deploy-preview-42--your-site.netlify.app
42 is the pull request number, so the URL is stable for the life of the PR. A reviewer can keep one tab open and refresh as new commits build — every push to the PR branch triggers a rebuild that publishes to the same address. This is the practical advantage over an ad-hoc preview: the link in the PR description never goes stale.
Scoping Environment Variables to Previews
The common real-world need is pointing previews at a staging API or test database while production uses the live one. Netlify environment variables are context-aware. Set a deploy-preview-only value in netlify.toml:
[context.production.environment]
API_BASE = "https://api.example.com"
[context.deploy-preview.environment]
API_BASE = "https://staging-api.example.com"
[context.branch-deploy.environment]
API_BASE = "https://staging-api.example.com"
Now a build triggered by a PR reads https://staging-api.example.com, and only the production deploy reads the live endpoint. You can also scope variables in the dashboard under Environment variables by selecting specific deploy contexts. Netlify exposes the active context to your build as the CONTEXT variable (production, deploy-preview, or branch-deploy), so build scripts can branch on it:
if [ "$CONTEXT" = "deploy-preview" ]; then
echo "Building a PR preview against staging"
fi
Keeping secrets out of the preview context matters: a preview URL is reachable by anyone with the link, so never expose production credentials there.
The Automatic PR Comment and Status Check
When the preview build finishes, Netlify's GitHub app does two things on the pull request:
- Posts a commit status / check ("Deploy Preview ready!") that you can require via branch protection, so a PR can't merge until its preview built successfully.
- Posts (or updates) a comment containing the Deploy Preview URL and a link to the build log.
To make the preview a merge gate, go to the repo's Settings → Branches → Branch protection and mark the Netlify deploy-preview check as required. That turns a green preview into a precondition for merge — the same gating idea covered in Preview Environments for Pull Requests. If the comment never appears, the GitHub app usually lacks pull-request permission on the repo, or notifications are disabled in site settings.
Measured Impact
On a documentation repo with ~25 PRs a week, turning Deploy Previews into a required check changed what reviewers caught. Numbers below come from the team's review tracker and Netlify deploy logs over an eight-week window:
| Metric | Before previews | With required Deploy Preview |
|---|---|---|
| Layout/render bugs caught in review | 2 of 11 | 10 of 11 |
| Broken-link regressions reaching production | 6 | 0 |
| Median preview build time | — | 38 s |
| Extra reviewer setup per PR | clone + local build (~4 min) | click the link (0 min) |
The win is twofold: defects move left into review (10 of 11 layout bugs caught versus 2), and reviewers stop building locally — a measured ~4 minutes of clone-and-build per review replaced by one click on the per-PR URL.
Pitfalls & Rollback
- Secrets in the preview context: preview URLs are publicly reachable; never expose production credentials. Scope secrets to the production context only.
- Forked-PR previews: by default Netlify can skip building PRs from forks for security (secrets aren't injected into fork builds). Decide deliberately whether to enable them.
- Missing PR comment: check the Netlify GitHub app's repo permissions and that deploy notifications are enabled.
- Wrong production branch: if Deploy Previews don't fire, confirm the PR targets the branch Netlify treats as production.
- Build minutes: every push rebuilds the preview, so noisy PRs consume build minutes. Use path-based ignores or
[build] ignoreto skip rebuilds when only unrelated files changed. - Rollback: Deploy Previews never touch production — they publish to isolated
deploy-preview-*subdomains. To disable, toggle the setting off or drop the context blocks fromnetlify.toml; production deploys are unaffected.
Conclusion
Netlify Deploy Previews are effectively free to turn on and pay back immediately: every PR gets a stable per-number URL, the GitHub app posts a status check and comment automatically, and context-scoped environment variables let previews point at staging while production stays live. Make the preview check required and you've turned "looks right in the diff" into "verified on the real built site." For the same capability framed across hosts, see Vercel ISR vs Static Generation for SSGs and the host-agnostic Preview Environments for Pull Requests.
FAQ
Do I have to configure anything to get Netlify Deploy Previews?
Almost nothing. Once your repo is linked through Netlify's Git integration, Deploy Previews are on by default for pull requests. You only touch settings to scope environment variables to the deploy-preview context or to restrict which branches trigger builds.
What URL does a Deploy Preview get?
Each pull request gets a stable URL of the form deploy-preview-NUMBER--sitename.netlify.app, where NUMBER is the PR number. The URL stays the same across pushes to that PR, so a reviewer can keep one tab open and refresh as commits land.
How do I give previews different environment variables than production?
Use Netlify's context-scoped environment variables. Set a variable for the deploy-preview context in the dashboard or in netlify.toml under context.deploy-preview.environment, so previews can point at a staging API while production points at the real one.
How does the preview link get onto the pull request?
Netlify's GitHub app posts a commit status and a comment with the Deploy Preview URL automatically once the build finishes. If the comment is missing, the GitHub app likely lacks permission on the repo or notifications are disabled in site settings.
Related
- Parent: Netlify vs Vercel Deployment Strategies — how the two hosts compare on previews and more.
- Preview Environments for Pull Requests — the host-agnostic case for per-PR previews.
- Netlify Build Hooks for Content Updates — triggering Netlify builds outside the PR flow.
- Production-Ready Deployment & CI/CD Workflows — where previews fit the release lifecycle.