Because nobody looked at the change on a real URL before it shipped. Someone described the edit in a message, someone else approved it from the description, and the first time anyone saw it rendered was after it was live. Most production mistakes we get called about are review failures, not code failures.
The fix has been around for years and it is still unevenly adopted. Every change gets its own working URL, and nobody approves anything they have not opened in a browser. That is the whole discipline.
What has changed is that you no longer need to maintain a separate server to get it. The hosting platforms build a throwaway copy of your site for every change, automatically, and throw it away when you are done.
A staging site is a second, private copy of your website that mirrors production as closely as possible. You push changes there first, check them, and only then push to the live site. Traditionally it lived at a subdomain like staging.yoursite.com and ran all year whether anyone was using it or not.
The idea is sound and it predates modern hosting by decades. The problem was never the concept. It was the maintenance. A long-lived staging environment drifts from production, accumulates stale data, breaks in ways nobody notices for weeks, and becomes another thing to patch and pay for.
The other problem was granularity. One staging site means one queue. If two people are working on different changes, they either take turns or they overwrite each other, and the thing you are reviewing is a mixture of two unrelated edits.
A deploy preview is a full, working copy of your site built automatically for a single change, at its own URL. It appears when you open a pull request, lasts as long as you need it, and disappears from relevance once the change ships. Instead of one shared staging site, you get one per change.
Vercel documents three default environments: Local for development on your own machine, Preview for "deploying for further testing, QA, or collaboration without impacting your live site", and Production for the user-facing site. Vercel creates a preview deployment when you push a commit to a branch that is not your production branch, open a pull request on GitHub, GitLab, or Bitbucket, or deploy from the CLI without the production flag.
Vercel also gives you two kinds of preview URL, which is a distinction worth understanding. A branch-specific URL always points at the latest changes on that branch. A commit-specific URL points at one exact deployment. For review, the commit-specific URL is the honest one, because the thing you approved cannot change underneath you afterwards.
Netlify works the same way with different naming. Its Deploy Previews are generated from pull requests and published to a URL with a predictable shape. Netlify's documentation gives the example that a Deploy Preview for pull request 42 deploys to deploy-preview-42--mysitename.netlify.app. Netlify also has branch deploys, which are longer-lived and sit at a stable URL like staging--mysitename.netlify.app.
Not on the major platforms, because they block it for you. Both Vercel and Netlify send a noindex header on preview URLs automatically. This used to be one of the most common ways a site leaked duplicate content into search results, and the platforms fixed it by making the safe behaviour the default.
Vercel is explicit about the mechanism. Its documentation states that "by default, Vercel Preview Deployments aren't indexed by search engines" and that "Vercel adds an X-Robots-Tag: noindex HTTP response header to every Preview Deployment automatically." It also applies to superseded production builds: when you promote a new deployment to production, the previous one starts returning noindex.
Netlify describes the same protection with a wider scope. Its documentation says that "Netlify automatically ensures that only your currently published production deploy and most recent branch deploys can be indexed by search engines" and that "requests to Deploy Previews, unpublished production deploys, and old branch deploys will have an X-Robots-Tag: noindex header included in the response."
There is one gap worth knowing about, and it catches people. Vercel's documentation notes that it "omits X-Robots-Tag: noindex when a custom domain is assigned to a non-production branch." So the moment you give your staging branch a friendly domain, the automatic protection stops and the responsibility moves to you. If you do that, add the header yourself in your project configuration, and check it with your browser devtools before you assume it is there.
Sometimes, and it is a narrower case than most teams assume. Per-change previews handle review. A persistent staging environment earns its place when something needs to exist continuously: integration testing against third-party services, a stable URL for a client to bookmark, or a place to rehearse data migrations.
Vercel supports this directly through custom environments, which its documentation describes as useful "for longer-running pre-production environments like staging, QA, or any other specialized workflow you require." These are a paid-tier feature, and Vercel documents the limits plainly: one custom environment per project on Pro, and twelve per project on Enterprise.
Our default for a marketing site is previews only. A brochure site, a services site, or a content-driven site has no long-running integration surface to test, and adding a permanent staging environment adds a thing to maintain in exchange for very little. The moment there is a payment flow, a CRM sync, or a booking system in the mix, the calculation changes and we add one.
Then buy the discipline manually. Most hosted site builders have some notion of an unpublished state or a separate preview domain, and the important thing is to use it deliberately rather than editing the live site and hoping. The mechanism matters less than the rule that nobody approves work they have not opened.
Where platforms differ most is in whether two people can work on separate changes at once. Many hosted builders have a single shared editing state, which means concurrent edits collide the way an old shared staging server did. If your platform works that way, the practical answer is sequencing: one change in flight at a time, reviewed and published before the next one starts.
Webflow has its own approach to reviewing changes before they reach the live site, and we wrote about it separately in our piece on Webflow page branching. The shape of the problem is the same on every platform even when the tooling is not.
More than whether it looks right. A preview URL is a real build on real infrastructure, so it is the correct place to test the things that only appear in a built site: responsive behaviour at real breakpoints, form submissions, third-party embeds, and how the page performs when it is served rather than running on someone's laptop.
The check we insist on most is mobile. A change reviewed only on a desktop monitor will ship a broken phone layout, and a preview URL costs nothing to open on an actual device. Sending the link to a phone takes five seconds and catches a category of bug that no amount of browser resizing will.
The other one is content, not code. Preview links are the last realistic chance for the person who owns the words to read them in place. Copy that reads fine in a document often reads badly in a narrow column next to an image. We keep a standing checklist for this, and it overlaps heavily with what we run before launch in our pre-launch testing process.
Every change gets a preview URL, and the URL goes into the review conversation instead of a description of the change. Nobody on our side approves work from a written summary. If a client asks "does it look right", the answer is a link they can open, not a paragraph telling them it does.
We also try to keep changes small enough that a preview is reviewable in a few minutes. A preview link attached to forty unrelated edits gets skimmed and rubber-stamped, which puts you back where you started. Small changes get looked at properly, and that is more valuable than any tooling.
The habit that has saved us the most trouble is reviewing on the commit-specific URL rather than the branch URL. Approving a moving target is not approval. If more work lands on the branch after sign-off, that is a new thing to look at, and the URL should reflect that. We go deeper on how we structure feedback in our notes on the design review process.
You need a reviewable URL for every change. On modern hosting that is a deploy preview, and it is better than a staging site because it is per-change, automatic, and disposable. Keep a persistent staging environment only when something genuinely needs to run continuously, and be honest about whether yours does.
If your team is still editing production directly, that is the thing to fix first, ahead of any tooling decision. The platforms have made the safe path the default one, including the search-engine protection that used to require manual work. Most of the benefit is available the moment you start using pull requests.
If you are not sure how your current setup handles previews, or you inherited a site with a staging server nobody quite trusts, we are happy to take a look and tell you what is worth keeping. Reach out through phoenix.studio and we will walk through it with you.
Tell us where you want to go. We'll tell you how we'd get you there.