Vercel’s custom-domain UX is one of the cleanest in the industry — but “cleanest” is not “no traps”. This article walks through the actual flow with copy-paste DNS records, then names the four mistakes that account for ~90% of the support questions.
Background
Vercel issues free SSL via Let’s Encrypt and accepts both apex and www in the same project. The platform automatically creates the redirect between them once both are added. DNS is the only step you do yourself, and it is also the only step that can hold up SSL provisioning.
How to tell
- You already have a Vercel project working at
*.vercel.app. - You own the domain at a registrar (Cloudflare, Porkbun, Namecheap, etc.).
- You want both apex and www to resolve.
- You can edit DNS at the registrar (or via Cloudflare API).
Quick verdict
Add the domain in Vercel UI → copy the DNS records → set them at the registrar → wait for green check → add the variant → set canonical to one.
Before you start
- Lower DNS TTL to 300s 24 hours before the change.
- Decide canonical (apex or www) before adding either.
- Remove old A/CNAME records pointing at a previous host.
Step by step
-
Add the domain in Vercel. Project → Settings → Domains → type
yourdomain.com→ Add. Vercel displays the records needed. -
DNS records (typical):
For apex (yourdomain.com):
Type Name Value TTL
A @ 76.76.21.21 300
For www (www.yourdomain.com):
Type Name Value TTL
CNAME www cname.vercel-dns.com. 300
- Apply the records at your registrar. Cloudflare API example:
curl -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE/dns_records" \
-H "Authorization: Bearer $CF_TOKEN" \
-H "Content-Type: application/json" \
--data '{"type":"A","name":"@","content":"76.76.21.21","ttl":300,"proxied":false}'
curl -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE/dns_records" \
-H "Authorization: Bearer $CF_TOKEN" \
-H "Content-Type: application/json" \
--data '{"type":"CNAME","name":"www","content":"cname.vercel-dns.com","ttl":300,"proxied":false}'
Note proxied: false — Cloudflare’s orange-cloud proxy interferes with Vercel’s certificate issuance. Use DNS-only (grey cloud) at least until SSL is issued.
- Verify DNS has propagated before clicking refresh in Vercel:
dig +short A yourdomain.com @1.1.1.1
# 76.76.21.21
dig +short CNAME www.yourdomain.com @1.1.1.1
# cname.vercel-dns.com.
- Wait for Vercel’s “Valid Configuration” check. Vercel polls every few minutes. SSL provisions automatically — usually under an hour. While it works:
curl -vI https://yourdomain.com 2>&1 | grep -E 'subject:|issuer:|HTTP'
# subject: CN=yourdomain.com
# issuer: C=US, O=Let's Encrypt, CN=...
# HTTP/2 200
- Add the second variant. If you added apex, now add www (or vice versa). Vercel automatically creates a 308 redirect from the non-canonical variant to the canonical. Verify:
curl -sI https://www.yourdomain.com | head -3
# HTTP/2 308
# location: https://yourdomain.com/
- Set canonical, sitemap, and
og:urlto the chosen primary domain in code:
<link rel="canonical" href={`https://yourdomain.com${Astro.url.pathname}`} />
Grep to verify:
grep -ROIE 'rel="canonical"|og:url' dist | grep -v 'https://yourdomain.com' | head
# any output = a leak (e.g., vercel.app, www variant, http)
- If you want to keep Cloudflare proxy on (orange cloud), enable it only AFTER SSL is issued on Vercel. Then in Cloudflare set SSL mode to “Full (strict)” —
Fullworks but is less strict;Flexiblewill cause an infinite redirect loop.
Implementation checklist
- A record for apex + CNAME for www, both at the registrar, both DNS-only.
- DNS resolves correctly from at least two resolvers.
- SSL cert subject matches the domain (
curl -vIconfirms). - Both apex and www are added in Vercel; one is canonical, one redirects 308.
- Canonical tag site-wide points only at the canonical version.
After-launch verification
- Search Console URL Inspection on the new domain shows “URL is on Google” within 1-2 weeks (if previously verified).
- Lighthouse loads with valid HTTPS and no mixed-content warnings.
- Vercel Domains tab shows green check on both apex and www.
Common pitfalls
- Using your registrar’s nameservers and adding records elsewhere — DNS is split, Vercel sees nothing.
- Cloudflare’s orange-cloud proxy fighting Vercel’s SSL — turn off the proxy on the records, or use Cloudflare-as-DNS-only.
- Adding only apex and forgetting www (or vice versa) — half your traffic 404s.
- Long TTL on old records so DNS swaps slowly — lower TTL before you swap, not after.
- Forgetting to remove the previous host’s A record — DNS round-robins between live and dead hosts.
- Setting Cloudflare SSL to “Flexible” — creates a redirect loop because Cloudflare → origin uses HTTP while origin enforces HTTPS.
FAQ
- How long does SSL take?: Usually under an hour after DNS is correct. If it is stuck for hours, re-check the DNS values exactly match what Vercel showed.
- Apex or www as primary?: Either works in 2026. Pick one and keep canonical / sitemap consistent across the site.
- Can I host the same project on multiple domains?: Yes, but pick one canonical to avoid duplicate-content SEO issues.
- What about Cloudflare in front of Vercel?: Possible but tricky — disable the proxy (grey cloud) for the Vercel records, or run Cloudflare in DNS-only mode.
- The same domain works on Vercel but is “needs setup” on Firebase.: Vercel issues the cert from the CNAME / A record directly; Firebase needs a separate TXT ownership step first (why a domain works on Vercel but not Firebase).