Skip to content

Custom Domains

Domain and DNS questions come up because they are the part of deployment that most developers have never actually done.


1. DNS Basics

RecordPoints toUse
AAn IPv4 addressApex domain (example.com)
AAAAAn IPv6 addressApex domain, IPv6
CNAMEAnother domain nameSubdomains (www.example.com)
TXTArbitrary textDomain verification, SPF, DKIM
MXA mail serverEmail
NSNameserversDelegating who answers for the zone

The Apex Domain Problem

The DNS spec does not allow a CNAME at the apex (example.com). A CNAME replaces all other records at that name, which would break your MX records — you'd lose email.

That is why platforms give you an A record for the apex and a CNAME for www.

Some DNS providers offer ALIAS / ANAME / "CNAME flattening" (Cloudflare) — a CNAME-like record at the apex that resolves server-side. If your provider supports it, use it: the platform can change IPs without breaking you.

Knowing why the apex can't be a CNAME is a genuinely good interview answer — most people have only followed the instructions.


2. Adding a Domain to Vercel

  1. Project → Settings → Domains → add example.com
  2. Vercel shows the records to create
  3. Add them at your registrar (Namecheap, GoDaddy, Cloudflare)
  4. Wait for propagation
  5. Vercel issues a TLS certificate automatically

Typical Records

Type    Name    Value
A       @       76.76.21.21
CNAME   www     cname.vercel-dns.com

Or Delegate Nameservers

Point your registrar at Vercel's nameservers and Vercel manages the whole zone. Simpler, but you lose direct control of MX and other records — fine for a project domain, less so for a company domain that also handles email.


3. Propagation

DNS changes are not instant. Resolvers cache records for the TTL duration.

TTLMeaning
300 (5 min)Fast changes, more DNS queries
3600 (1 hour)Common default
86400 (24 hours)Slow to change, fewest queries

The Migration Trick

Lower the TTL to 300 a day before you migrate. Then the switch propagates in minutes instead of a day. Raise it again afterwards.

This one detail is the difference between a planned migration and a stressful one.

Checking

bash
dig example.com A +short
dig www.example.com CNAME +short
nslookup example.com 8.8.8.8    # query a specific resolver

Your own machine caches too — dig against 8.8.8.8 shows what the wider internet sees, not what your laptop remembers.


4. www vs Apex — Pick One

Serve one canonical hostname and 301 redirect the other.

example.com      → redirects to → www.example.com

or the reverse. Vercel does this in Domains settings.

Why It Matters

ReasonDetail
SEOTwo URLs serving identical content splits ranking signals
CookiesA cookie on the apex is sent to every subdomain, including a compromised one
AnalyticsTraffic split across two hostnames
CertificatesFewer names to manage

The cookie point is the one people miss and the strongest technical argument for www: a cookie set on example.com is sent to staging.example.com, blog.example.com and anything else. Setting it on www.example.com scopes it to that host only.


5. HTTPS and Certificates

Vercel provisions and renews Let's Encrypt certificates automatically. Nothing to do.

Requirements

  • DNS must point at Vercel before the certificate can be issued (domain validation)
  • If you use Cloudflare, set SSL mode to Full (strict). "Flexible" means Cloudflare talks HTTP to your origin, which is unencrypted on the last hop and can cause redirect loops

HSTS

ts
{
  key: "Strict-Transport-Security",
  value: "max-age=63072000; includeSubDomains; preload",
}

Tells browsers to only ever use HTTPS for this domain.

Warning worth stating: HSTS is hard to undo. Once a browser has cached the header, it refuses HTTP for max-age seconds — you cannot fix a broken certificate by falling back to HTTP. Add preload only when you are certain every subdomain has HTTPS working.


6. Redirects

Domain-Level (Vercel Settings)

Set one domain as the redirect target of another. Handled at the edge, before your app runs — the fastest option.

Application-Level

ts
// next.config.ts
async redirects() {
  return [
    { source: "/old-blog/:slug", destination: "/blog/:slug", permanent: true },
    {
      source: "/:path*",
      has: [{ type: "host", value: "old-domain.com" }],
      destination: "https://new-domain.com/:path*",
      permanent: true,
    },
  ];
}

301 vs 302

301 Permanent302 Temporary
SEOPasses ranking to the targetKeeps ranking on the original
Browser cachingCached aggressivelyNot cached
Use forDomain moves, permanent URL changesA/B tests, temporary maintenance

A wrong 301 is painful. Browsers cache it hard, so users who hit the bad redirect keep following it even after you fix it. Use 302 while you're unsure, then switch to 301 once the destination is final.

permanent: true in Next.js means 308, false means 307 — the modern equivalents that preserve the HTTP method.


7. Subdomains

www.example.com      → the marketing site
app.example.com      → the application
api.example.com      → the backend
docs.example.com     → documentation
staging.example.com  → staging

Each can be a separate Vercel project, or a different host entirely. Add a CNAME per subdomain.

Wildcard Domains

*.example.com for multi-tenant apps (acme.example.com, globex.example.com). Requires nameserver delegation to Vercel for the wildcard certificate, and you read the tenant from the Host header in proxy.ts.

Cookies Across Subdomains

js
// Shared across all subdomains — convenient, and a wider blast radius
res.cookie("session", token, { domain: ".example.com" });

// Scoped to one host — safer
res.cookie("session", token, { /* no domain — defaults to the exact host */ });

Security note: a cookie on .example.com is sent to every subdomain. If any subdomain is compromised — an old staging box, a third-party-hosted blog.example.com — it receives your session cookie. Scope cookies as narrowly as the product allows.


8. Email and the Apex

A very common real-world break: adding a domain to a hosting platform and losing email.

MX   @   10 mx1.your-email-provider.com
TXT  @   "v=spf1 include:_spf.provider.com ~all"
  • MX records live on the apex alongside the A record — they coexist fine
  • If you delegate nameservers to Vercel, you must recreate MX, SPF, DKIM and DMARC records there, or email silently stops
  • This is why a CNAME at the apex is forbidden — it would wipe the MX records

Screenshot the existing DNS zone before changing nameservers. Recovering a mail configuration from memory is not fun.


9. Troubleshooting

SymptomCause
"Invalid Configuration" in VercelDNS records don't match; check for a typo or a leftover old A record
Domain works, www doesn'tMissing CNAME for www
Certificate pending for hoursDNS hasn't propagated, or a CAA record blocks Let's Encrypt
Redirect loopCloudflare SSL set to "Flexible" instead of "Full (strict)"
Old site still showingLocal DNS cache or browser cache — check with dig @8.8.8.8
Email stopped after migrationMX records not recreated after nameserver delegation
Works in incognito, not normallyCached 301 redirect in the browser

CAA Records

CAA  @  0 issue "letsencrypt.org"

A CAA record restricts which certificate authorities may issue for your domain. If one exists and doesn't include Let's Encrypt, certificate issuance silently fails. An obscure cause that wastes hours — worth knowing it exists.

© 2025 DDocs · Dipak's Documentation Guide