If your Production site is accessible at both your-project.vercel.app and a custom domain (for example, https://your-custom-domain.com), search engines can treat those URLs as separate pages which can potentially affect your SEO performance.
Vercel Preview deployments are not indexed by search engines by default because the X-Robots-Tag HTTP header is set to noindex automatically by Vercel. However, if you're using a custom domain that is assigned to a non-Production branch, the header X-Robots-Tag: noindex will not be set.
This guide walks you through the three-step process Vercel recommends to ensure crawlers recognize one canonical version of each page, while still letting you (and your users) preview deployments on the vercel.app host.
Add a <link rel="canonical" …> tag in the <head> of every HTML page so that crawlers know which host (and scheme) is authoritative:
<link rel="canonical" href="https://your-custom-domain.com/{{ pathname }}" />
- Use the absolute HTTPS URL including any trailing slash or path segments.
- In frameworks like Next.js or SvelteKit, place this in your shared document/layout component so it’s injected automatically.
The X-Robots-Tag: noindex header tells search engines and crawlers to drop the page from their indexing entirely. This can be configured using vercel.json or using framework-level configurations (e.g. next.config.js) (preferred).
If your framework supports headers() (Next.js) or a similar API, use this by default as framework headers are merged after vercel.json:
// next.config.jsmodule.exports = { headers: async () => [ { source: '/:path*', has: [{ type: 'host', value: 'your-project.vercel.app' }], headers: [{ key: 'X-Robots-Tag', value: 'noindex' }] } ]};If your framework doesn't support implementing headers, or you prefer a simpler approach, you can set the tag in your vercel.json configuration instead:
{ "headers": [ { "source": "/(.*)", "has": [{ "type": "host", "value": "your-project.vercel.app" }], "headers": [{ "key": "X-Robots-Tag", "value": "noindex" }] } ]}Even with the X-Robots-Tag: noindex header enabled, users could still visit your vercel.app URL directly. To handle this, create a WAF Custom Rule that issues an HTTP Redirect to the canonical domain:
Setting | Value |
|---|---|
If | Hostname is any of or Equals |
Then | Redirect to |
- Go to Project → Firewall in the Vercel Dashboard.
- Click Add Rule → name it “Redirect to canonical”.
- Configure the condition and action as above.
- Click Save Rule – changes propagate globally without requiring a new deployment.

Learn more about WAF Custom Rule configurations: https://vercel.com/docs/vercel-firewall/vercel-waf/custom-rules
Verify your changes:
1. Perform a curl lookup for your project's vercel.app URL and confirm the response header:
curl -I https://your-project.vercel.app
X-Robots-Tag: noindex should be surfaced in the response.
- X-Robots-Tag: noindex → prevents
.vercel.apppages from entering the index.
2. Inspect the HTML source of your custom domain and confirm the canonical tag points to the same host.
- Canonical tag → tells search engines which URL to rank.
3. Manually navigate to your project's vercel.app URL in a browser to verify your WAF redirect works as intended.
- WAF Redirect → ensures humans (and link equity) end up on the canonical host.
4. Use Google Search Console’s URL Inspection tool to check your domain's indexing status: https://support.google.com/webmasters/answer/9012289?hl=en
With these four layers in place, you’ll avoid duplicate-content penalties while retaining all the convenience of Vercel Preview Deployments and multiple domains.
If you have questions or need further assistance, contact Vercel Support.