Custom domains and automatic SSL
Point a domain you own at your Vercel deployment with DNS records, and let Vercel provision and renew the HTTPS certificate.
Your app is live, but your-project.vercel.app is the wrong URL to put in front of a customer: it’s unbranded and it reads as “not a real product yet.” Going live properly means a domain you own, resolving to your app, served over HTTPS with a padlock in the address bar.
On Vercel, that padlock is free and automatic. You point your domain at Vercel with two DNS records, and Vercel provisions and renews the certificate for you. So the hard part isn’t the lock, it’s the pointer: DNS is your job, TLS is Vercel’s. The one decision you make is apex versus www, and the one pitfall is putting Cloudflare in front of Vercel.
A custom domain is a DNS pointer plus automatic TLS
Section titled “A custom domain is a DNS pointer plus automatic TLS”A live custom domain is two independent concerns, easy to fuse into one:
- The pointer, DNS. The domain name has to resolve to Vercel’s edge: when a browser looks up
app.example.com, the answer has to lead to Vercel. That answer is a DNS record you create at your registrar. This half is your job, and you do it once. - The lock, TLS. Browsers won’t serve a modern site over plain HTTP; the domain needs a valid certificate to be reachable over HTTPS. That’s TLS , proven by a TLS certificate . This half is Vercel’s job, and it’s fully automatic.
You already understand half of this. The first lesson of this chapter showed that “production” isn’t a deployment, it’s a pointer: an alias Vercel re-aims at whichever immutable deployment is current. A custom domain adds a second pointer, one hop upstream. DNS points your domain at Vercel’s edge, and Vercel’s alias points its edge at the live deployment, so a browser request travels through both pointers in series.
When something goes wrong, it’s almost always the pointer that’s misconfigured or still propagating, never the lock, which isn’t yours to misconfigure.
Apex versus www: pick one canonical
Section titled “Apex versus www: pick one canonical”This decision is effectively irreversible: you can flip it after launch, but that becomes a migration with redirect and SEO cost. So decide once, now.
The choice is which form of your domain is the real one:
- Apex is
example.com, the bare domain with nothing in front. It’s the shortest expression of your brand and the modern default for a marketing site. wwwiswww.example.com. It’s historically easier to configure, for the reason you’ll see in the next section.
The rule matters more than the choice: pick one as canonical and redirect the other to it. If example.com and www.example.com independently serve the same content, search engines see two sites with identical pages. That’s duplicate content, which dilutes your ranking, and your inbound links fragment across two addresses instead of accumulating on one. The fix is a permanent redirect (a 301 or 308) from the non-canonical form to the canonical one, which Vercel adds for you once you’ve added both forms and marked one as primary.
For this course, the default is apex canonical: example.com is the real address, and www.example.com permanently redirects to it.
The apex won’t be your only name forever. A common split puts marketing on the apex, the app on app.example.com, and docs on docs.example.com, and multi-tenant products later give each customer their own subdomain. That per-tenant routing is its own topic for later; today you’re wiring one domain.
You’re launching the marketing site for a new product and want the cleanest brand URL you can put on a business card. How should you wire example.com and www.example.com?
example.com as the real address and have www.example.com permanently redirect to it.www.www.example.com as the real address, since a bare domain like example.com can’t be pointed at Vercel at all.example.com the real address and turn www.example.com into its own standalone landing page.www landing page is just that trap in disguise. The apex can be wired to Vercel (with an A or ALIAS record); it’s only the CNAME shortcut that’s off-limits there.The two DNS records, and why the apex is the awkward one
Section titled “The two DNS records, and why the apex is the awkward one”The confusion here comes from one quirk: the cleanest kind of DNS record is forbidden at exactly the address most people want to use.
Start with the easy case. For www, or any subdomain, you create a CNAME : an alias that says “go look that other name up instead.” You point www.example.com at the target Vercel gives you, and you’re done. CNAMEs are standard, supported by every registrar, and they track changes automatically: if Vercel moves the underlying address, the CNAME still resolves, because it points at a name, not a fixed address.
The apex is where the quirk lives. The DNS specification forbids a CNAME at the apex, for a structural reason: the zone root has to coexist with the mandatory records that define the zone itself (its SOA and NS records), and a CNAME can’t share a name with any other record. Since example.com already carries those records, it can’t also be a CNAME.
There are two ways around it:
- An
Arecord. An A record points the apex straight at Vercel’s IP. This always works. The catch is that you’re hardcoding a specific address that is Vercel’s to change, so you copy the current value from your dashboard rather than memorizing it. Vercel serves that one IP fast from everywhere using anycast . - An
ANAME/ALIASrecord. This is a special record type some registrars offer. You point it at Vercel’s name, and it auto-tracks any address change, just like a CNAME. Prefer it when available: you get the A record’s reach without the hardcoded address.
So the apex rule is: use ANAME/ALIAS if your registrar offers it, and fall back to the A record if it doesn’t.
One thing matters more than any specific value: never treat a particular Vercel IP or CNAME target as authoritative. Vercel issues these per project and rotates them, so a value that’s correct today may change. Always copy whatever Settings → Domains shows for this specific project. Everything below is a labeled example, never a string to memorize.
| Type | Name | Value | TTL |
|---|---|---|---|
CNAME | www | <project>.vercel-dns-NNN.com | 300 |
The Value is an example: copy your per-project value from Settings → Domains, never from a tutorial.
| Type | Name | Value | TTL |
|---|---|---|---|
A | @ | <Vercel anycast IP — read from dashboard> | 300 |
ALIAS | @ | <project>.vercel-dns-NNN.com | 300 |
@ is how registrars write “the apex / zone root”. Both Values are examples: read the live per-project values from Settings → Domains.
You don’t go hunting for these values; Vercel hands them to you.
-
In your project on Vercel, go to Settings → Domains and enter the domain to add (start with the apex,
example.com). -
Vercel shows you the exact record or records to create, scoped to your project: the type, the name, and the value. This is the authoritative value to copy.
-
Create those records at your registrar, wherever you bought the domain, since that’s where DNS lives.
-
Wait. Vercel polls your DNS in the background and flips the domain from Invalid Configuration to Valid Configuration once it sees the record.
Set the following record on your DNS provider to continue. Vercel will detect it automatically.
Redirects to example.com · Certificate issued automatically.
DNS propagation and the automatic certificate
Section titled “DNS propagation and the automatic certificate”You created the record, the dashboard still says Invalid Configuration, and nothing seems to be happening. Almost always nothing is broken; you’re just inside the wait.
The wait is called propagation . When you change a record, resolvers everywhere have cached the previous answer and keep serving it until their cache expires. How long they hold it is set by the record’s TTL . So the gap between “saved at the registrar” and “Vercel sees it” can be seconds or hours, with the ceiling fixed by the old record’s TTL. Vercel polls and updates the status pill on its own, so your job here is to wait, not to edit.
One move makes future changes painless: lower the TTL before a change, then raise it back after. A day before you cut over a record, drop its TTL to something small, like 300 seconds. Caches now hold the old value for only five minutes, so the cutover window is short. Once everything’s stable, raise it back to an hour or more. You can’t shrink the wait for this change, since the old TTL already set it, but you can make the next one quick.
The moment your DNS resolves to Vercel, Vercel requests a TLS certificate from Let’s Encrypt , installs it on your domain, and renews it before it expires. No signing request, no file upload, no cron job, no renewal outage at 2 a.m. The whole certificate ritual collapses into one instruction: wait for the status to go green.
One piece of HTTPS is not automatic. Vercel redirects plain HTTP to HTTPS on custom domains, so visiting http://example.com bounces you to https://. But the header that tells browsers to never even try plain HTTP again, Strict-Transport-Security, or HSTS , is an application-level response header, and that one is your job. It lives in next.config.ts with your other security headers, and you’ll set it in the launch-checklist lesson at the end of this chapter. The redirect is automatic; the HSTS header is yours and comes later.
Putting Cloudflare in front without breaking TLS
Section titled “Putting Cloudflare in front without breaking TLS”This pitfall stays invisible until someone audits it, which is why it belongs on a checklist. First, the recommendation has shifted.
Vercel now discourages putting a Cloudflare proxy in front of it. Proxying through Cloudflare blinds Vercel’s own Firewall and bot protection, since Vercel then sees Cloudflare’s IPs instead of your visitors’; it adds a hop of latency; and it complicates caching. Vercel’s built-in Firewall is the default edge-security answer, so reach for it first. Teams still front Vercel with Cloudflare for specific reasons, such as existing Cloudflare WAF rules or multi-origin edge logic Vercel doesn’t cover, and if you’re one of them, here is the rule that keeps the setup from being silently insecure.
When you front Vercel with Cloudflare, you move your domain’s nameservers to Cloudflare and let it proxy requests through to Vercel (the “orange cloud”, or proxy-on, mode). You no longer have one TLS connection; you have two TLS hops end to end:
- Browser to Cloudflare, encrypted with Cloudflare’s own edge certificate.
- Cloudflare to Vercel, a second connection secured by Vercel’s origin certificate, the Let’s Encrypt one from the previous section.
Beginners model this as one connection with one lock, when it’s really two connections that each need their own lock. Whether that second hop is locked depends entirely on one Cloudflare setting, the SSL/TLS encryption mode. Three values matter, and only one is correct:
- Flexible leaves the Cloudflare-to-Vercel hop as plain, unencrypted HTTP. The browser still shows a padlock, because the first hop is encrypted, but your traffic crosses the public internet to Vercel in the clear. Worse, Vercel is HTTPS-only and redirects the plain request back to HTTPS, giving you a redirect loop. Wrong and insecure.
- Full encrypts the origin hop but does not validate Vercel’s certificate. The traffic is encrypted, yet Cloudflare accepts any certificate on the far end, so the connection is spoofable. Better than Flexible, still not safe.
- Full (strict) encrypts the origin hop and validates Vercel’s certificate. The only mode that is genuinely encrypted and verified end to end.
From the browser, the padlock looks identical in all three modes, but only Full (strict) is actually end-to-end secure. The difference is invisible unless someone inspects that second hop, which is why it slips into production and stays there.
Each claim is about running Cloudflare in front of Vercel. Mark each statement True or False.
The browser shows a padlock, so the connection is encrypted end to end.
“Full (strict)” is the only Cloudflare SSL/TLS mode that both encrypts the origin hop and validates Vercel’s certificate.
Putting Cloudflare in front of Vercel is the recommended default for a 2026 SaaS.
Reveal card-by-card review
One operational footnote. If the domain you’re adding is already attached to a different Vercel project, Vercel may ask you to prove control by adding a TXT verification record at your registrar. Add it, let Vercel verify, and leave it in place: Vercel re-checks it periodically, so deleting it later can break the domain’s attachment.
Proving the domain is ready
Section titled “Proving the domain is ready”A domain isn’t “done” because the dashboard turned green and it loaded once in your browser. “Done” is something you can prove, from outside your own machine, with a handful of commands. The first four have a clear pass condition; the fifth is the human one.
dig +short example.com @1.1.1.1 # returns Vercel's IP, not your old host'scurl -sI https://example.com # HTTP/2 200, no certificate errorcurl -sI http://example.com # 308 (or 301), Location: https://example.comcurl -sIL https://www.example.com # follows the redirect down to the apex# then open it in a browser: padlock present, click aroundWhy each command earns its place:
-
DNS resolves to Vercel.
digwith@1.1.1.1asks Cloudflare’s public resolver , deliberately bypassing your own machine’s cache. This is the most important habit in the list: querying from outside your laptop dodges the stale answer your own resolver may still be holding, the number-one source of “it works for me but not for them.” If this returns Vercel’s address, the pointer is real. -
HTTPS serves a valid certificate.
curl -sImakes a request and prints only the response headers. A clean200with no TLS complaint means the lock is in place. -
HTTP redirects to HTTPS. The same
curl -sIagainst the plainhttp://address should come back308(or301) with aLocationheader pointing athttps://, proving Vercel’s automatic redirect works. -
The canonical redirect works.
curl -sIL, where-Lfollows redirects all the way down, should sendwww.example.comto the apex. This proves your apex-versus-wwwdecision is wired up. -
Browser sanity check. Load it like a human would, confirm the padlock, and click around. Automated checks prove the plumbing; a real load proves the experience.
The habit that ties these together is verify from outside your own machine. Your laptop has its own caches and resolver and may have visited the old site minutes ago; a public resolver and a plain curl see what your customers see.
If the domain is already live elsewhere and you’re cutting it over to Vercel, that carries real downtime risk. Lower the TTL a day ahead so the cutover propagates in minutes rather than hours. Prepare the Vercel records before you flip anything, so the new target is ready the instant you change the pointer. Expect a window of partial propagation where some visitors hit the new site and some the old one, and remember the certificate provisions only after DNS resolves to Vercel, so there’s a short beat between “DNS points here” and “HTTPS works here.” Cut over during low traffic, and keep the old DNS records on hand: reverting the pointer is your rollback if the cutover goes wrong.
External resources
Section titled “External resources”Vercel's own walkthrough of the Settings → Domains flow, the record types, and the automatic certificate.
DNSimple's friendly, fully-illustrated walk through a lookup — the pointer half of this lesson, made vivid.
What the automated certificate authority behind Vercel's free, auto-renewing certificates is actually doing for you.
The reference for Flexible vs. Full vs. Full (strict) — read it before fronting any origin with Cloudflare.