Vercel 绑定自定义域名:确切 DNS 记录 + 5 个坑

把 apex + www 域名指到 Vercel——附确切的每项目 DNS 记录、dig/curl 验证、CAA 修复,以及 Cloudflare 前置又不破坏 SSL 的配置。内容更新至 2026 年 6 月。

Vercel 的自定义域名体验是行业里最干净的之一,但”干净”不等于”零陷阱”。本文给你确切的 DNS 记录(包括 Vercel 现在按项目分配的专属 CNAME)、可直接粘贴的 dig + curl 验证,以及”域名死活不变绿”客服帖里约 90% 都中招的 5 个错误。内容更新至 2026 年 6 月。

一句话总结

  1. 在 Vercel 里加上 yourdomain.com(apex),接受弹出的 www 提示。
  2. 复制 Vercel 控制台给你看的记录,不要照搬博客里的旧记录——CNAME 现在每个项目都不一样。
  3. apex 用 A 记录76.76.21.21),www项目专属 CNAME,两条都设为 DNS-only。
  4. dig 验证,等绿勾,再用 curl -vI 确认 SSL。
  5. 选一个主域(apex 或 www),另一个会自动 308 跳过去。

证书卡住时,原因几乎总是:旧记录没清、Cloudflare 橙云代理开着,或 CAA 记录把 Let’s Encrypt 挡在外面。

开始前你需要什么

  • 一个已经在 *.vercel.app 跑通的 Vercel 项目。
  • 一个你能控制的 registrar 上的域名(Cloudflare、Porkbun、Namecheap 等)。
  • 能在该 registrar 改 DNS(控制台或 API)。
  • 在加任何一个变体之前就先定好主域(apex yourdomain.com 还是 www.yourdomain.com)。

给独立开发者的一个许可证提醒:截至 2026 年 6 月,Vercel 的 Hobby 套餐免费但仅限非商业用途。如果你的自定义域名用于产品、付费客户或任何产生收入的场景,Vercel 条款要求升到 Pro 套餐($20/席位/月)。Hobby 每个项目最多挂 50 个自定义域名,但这不改变”非商业”这条规则。如果许可证对你重要,可看Firebase 自定义域名——Firebase 的免费 Spark 套餐允许商业使用。

动手改之前

  • 切换前 24 小时把现有 A/CNAME 记录的 TTL 调到 300s,让旧解析尽快过期。
  • 删掉仍指向旧 host 的 A/CNAME 记录。残留记录会让 DNS 在新旧源站之间来回轮询。
  • 确认你的域名 DNS 真的在你以为的地方托管(下面第 1 个坑:DNS 分裂)。

实操步骤

1. 在 Vercel 加域名

Project → SettingsDomains → 输入 yourdomain.comAdd Domain。加 apex 域名时,Vercel 会提示你顺带加上 www 前缀并建议把其中一个跳转到另一个。接受它。

2. 看 Vercel 给你的记录(这点变了)

大多数过时教程就错在这里。截至 2026 年,控制台给每个项目分配的是专属 CNAME,不再是那个通用的:

apex(yourdomain.com):
Type   Name   Value          TTL
A      @      76.76.21.21    300

www(www.yourdomain.com):
Type   Name   Value                                  TTL
CNAME  www    d1d4fc829fe7bc7c.vercel-dns-017.com.   300

A 记录的值 76.76.21.21 是 Vercel 的通用 anycast IP,apex 至今仍用它。而 CNAME 目标是按项目分配的——你看到的会像 d1d4fc829fe7bc7c.vercel-dns-017.com,而不是 cname.vercel-dns.com。旧的 cname.vercel-dns.com 仍能解析,但请复制你自己控制台打印的那个值。如果用 Vercel CLI,随时可以打印确切记录:

vercel domains inspect yourdomain.com

为什么 apex 用 A、www 用 CNAME?DNS RFC 1034 禁止在区域 apex 上放 CNAME(apex 本身就需要 NS/SOA 记录),所以 apex 用 A 记录,只有子域用 CNAME。

3. 在 registrar 配上这些记录

任何 registrar 用控制台都行。如果你脚本化 Cloudflare,关键是 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":"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":"d1d4fc829fe7bc7c.vercel-dns-017.com","ttl":300,"proxied":false}'

proxied: false 让 Cloudflare 保持 DNS-only(灰云)。橙云代理会拦截 HTTPS,导致 Vercel 无法完成 Let’s Encrypt 的 HTTP-01 验证,于是你会看到 “Failed to Generate Cert” / “Invalid Configuration”。至少在证书签发前保持灰云。

4. 去 Vercel 刷新前,先确认 DNS 已传播

dig +short A yourdomain.com @1.1.1.1
# 76.76.21.21

dig +short CNAME www.yourdomain.com @1.1.1.1
# d1d4fc829fe7bc7c.vercel-dns-017.com.

如果 dig 还返回旧 host,说明 TTL 没过期。等着就行——这时别急着在 Vercel 里删了域名重加。

5. 等 “Valid Configuration”,再确认 SSL

Vercel 每几分钟轮询一次,DNS 一旦正确就通过 HTTP-01 自动签发 Let’s Encrypt 证书,通常几分钟内完成。确认证书的 subject 和 issuer:

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

如果 DNS 正确却卡在 “Invalid Configuration” 超过一小时,通常是 CAA 记录没授权 Let’s Encrypt(见第 5 个坑)。

6. 确认非主域上的 308 跳转

apex 和 www 都加好后,Vercel 会把非主域 308 跳转到你选的那个。验证方向:

curl -sI https://www.yourdomain.com | head -3
# HTTP/2 308
# location: https://yourdomain.com/

7. 把 canonical、sitemap、og:url 都指向主域

在 Astro 布局里:

<link rel="canonical" href={`https://yourdomain.com${Astro.url.pathname}`} />

然后 grep 构建产物,揪出任何漏写成错误 host 的 URL:

grep -ROIE 'rel="canonical"|og:url' dist | grep -v 'https://yourdomain.com' | head
# 任何一行 = 漏(vercel.app、www 变体,或 http)

8.(可选)保留 Cloudflare 代理

如果你想用橙云做缓存/WAF,等 Vercel 签完 SSL 再开。然后在 Cloudflare 把 SSL/TLS 模式设为 “Full (strict)“Full 能用但不校验源站证书;Flexible 会造成无限重定向,因为 Cloudflare 用 HTTP 回源、而 Vercel 强制 HTTPS。

验证清单

检查项命令 / 位置期望结果
apex 解析dig +short A yourdomain.com76.76.21.21
www 解析dig +short CNAME www.yourdomain.com你的 *.vercel-dns-017.com 目标
都 DNS-onlyCloudflare DNS 标签两条记录都是灰云
证书有效curl -vI https://yourdomain.comsubject = 域名,issuer = Let’s Encrypt
跳转生效curl -sI https://www.yourdomain.com308 → 主域
canonical 干净dist 做 grep无非主域 URL
都绿勾Vercel → Domainsapex 和 www 都绿勾

卡住域名背后的 5 个坑

  1. DNS 分裂。 你把 nameserver 改到了 registrar,记录却加在别处(或反过来)。Vercel 啥也看不到。用 dig NS yourdomain.com 确认到底哪家在应答,把记录加到那边。
  2. 签发期间开着 Cloudflare 橙云。 代理拦截 HTTP-01 验证 →“Failed to Generate Cert”。证书签好前把记录设为 DNS-only(灰云)。
  3. 只加了 apex 或只加了 www。 另一半流量撞 404 或无跳转。两个都加,让 Vercel 处理 308。
  4. 旧记录 TTL 太长没过期。 你切了 DNS,但旧解析还在缓存里。切换之前就把 TTL 调到 300s,然后等旧 TTL 过期。
  5. CAA 记录挡住 Let’s Encrypt。 如果你的区域有 CAA 记录,它必须授权 Let’s Encrypt,否则签发会无声失败、显示 “Invalid Configuration”。加上或修正:
Type   Name   Value
CAA    @      0 issue "letsencrypt.org"

dig +short CAA yourdomain.com 查现有 CAA。完全没有 CAA 记录是没问题的(任何 CA 都可签发);只列了其他 CA 的 CAA 才会让 Vercel 出问题。

上线后

  • Search Console:对新 host 跑 URL Inspection;如果该资源此前已验证,1–2 周内应显示 “URL is on Google”。
  • Lighthouse:HTTPS 正常加载、无 mixed-content 警告。
  • Vercel → Domains:apex 和 www 都是绿勾。

FAQ

  • SSL 到底多久签? DNS 正确后通常几分钟,因为 Vercel 走 Let’s Encrypt 的 HTTP-01 验证。卡过一小时的话,重新核对 CNAME 目标、代理是否关掉、以及 CAA 记录。
  • 控制台显示了个奇怪的 CNAME,像 d1d4fc...vercel-dns-017.com,对吗? 对。截至 2026 年每个项目都有专属 CNAME 目标。照你控制台显示的复制;旧的通用 cname.vercel-dns.com 仍能解析,但已不是 Vercel 现在发给你的那个。
  • 主域选 apex 还是 www? 2026 年两个都行。选一个,全站 canonical、sitemap、og:url 保持一致。Vercel 文档倾向跳转到 www,但 apex 同样可以。
  • 一个项目能挂多个域名吗? 能,但要选一个 canonical、其余 308 跳过去,避免重复内容 SEO 问题。
  • 免费 Hobby 套餐能用自定义域名吗? 能加,但 Hobby 仅限非商业用途。产生收入的站点需要 Pro($20/席位)。想要免费的商业方案,Firebase Hosting 的 Spark 套餐允许商业使用。
  • 同一个域名挂 Vercel 没问题、挂 Firebase 却 “needs setup”? Vercel 直接从 A/CNAME 记录签发证书;Firebase 需要先单独完成 TXT 所有权验证(域名在 Vercel 能用、Firebase 不行)。

相关阅读

标签: #独立开发 #Vercel #部署 / 托管 #域名 #DNS #SSL