Vercel 绑定自定义域名

把自定义域名指到 Vercel——附确切 DNS 记录、dig + curl 验证、Cloudflare 前置而不破坏 SSL 的配置。

Vercel 的自定义域名体验是行业里最干净的之一——但”最干净”不等于”零陷阱”。本文走一遍真实流程,附可粘贴的 DNS 记录,然后点名占 90% 客服问题的 4 个错误。

问题背景

Vercel 通过 Let’s Encrypt 签免费 SSL,apex 和 www 都能加到同一个项目。两个都加好后平台自动建跳转。DNS 是你唯一手动操作的环节,也是唯一能卡住 SSL 的环节。

判断标准

  • Vercel 项目已经在 *.vercel.app 跑通。
  • 域名在 registrar(Cloudflare、Porkbun、Namecheap 等)。
  • 想 apex 和 www 都能解析。
  • registrar 上能改 DNS(或 Cloudflare API)。

快速结论

Vercel UI 加域名 → 复制 DNS 记录 → registrar 配 → 等绿勾 → 加变体 → canonical 指一个。

开始前准备

  • 切换前 24 小时把 DNS TTL 调到 300s。
  • 加任何变体前先选定主域(apex 或 www)。
  • 删旧 host 的 A/CNAME 记录。

实操步骤

  1. Vercel 加域名。 Project → Settings → Domains → 输 yourdomain.com → Add。Vercel 给出所需记录。

  2. 典型 DNS 记录:

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

www(www.yourdomain.com):
Type   Name   Value                     TTL
CNAME  www    cname.vercel-dns.com.     300
  1. registrar 配上。 Cloudflare API 写法:
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}'

注意 proxied: false——Cloudflare 橙云代理会干扰 Vercel 证书签发。至少证书签发前保持 DNS-only(灰云)。

  1. DNS 传播后再去 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.
  1. 等 Vercel 显示 “Valid Configuration”。 Vercel 每几分钟轮询。SSL 自动签——一般一小时内。期间:
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
  1. 加第二个变体。 加完 apex 加 www(反之亦然)。Vercel 自动建 308 跳转。验证:
curl -sI https://www.yourdomain.com | head -3
# HTTP/2 308
# location: https://yourdomain.com/
  1. 代码里 canonical、sitemap、og:url 都指主域:
<link rel="canonical" href={`https://yourdomain.com${Astro.url.pathname}`} />

grep 验证:

grep -ROIE 'rel="canonical"|og:url' dist | grep -v 'https://yourdomain.com' | head
# 有输出 = 漏(例如 vercel.app、www 变体、http)
  1. 要保留 Cloudflare 代理(橙云),Vercel SSL 签完再开。然后 Cloudflare SSL 模式选 “Full (strict)“——Full 行但不够严,Flexible 会无限重定向。

执行检查清单

  • apex 用 A、www 用 CNAME,registrar 上都 DNS-only。
  • 至少两个解析器返回正确。
  • SSL 证书 subject 与域名一致(curl -vI 验证)。
  • Vercel 里 apex 和 www 都加了;一个主,一个 308 跳转。
  • 全站 canonical 只指主域。

上线后验证

  • Search Console URL Inspection 在新域上 1-2 周内显示 “URL is on Google”(如已验证)。
  • Lighthouse 加载 HTTPS 正常、无 mixed-content 警告。
  • Vercel Domains 标签 apex 和 www 都绿勾。

容易踩的坑

  • 在 registrar 那边用了它的 nameserver,但记录配在别的地方——DNS 分裂,Vercel 啥也看不到。
  • Cloudflare 橙云代理和 Vercel SSL 打架——关橙云改灰云,或者 Cloudflare 只做 DNS。
  • 只加了 apex 或只加了 www——另一半流量 404。
  • 老记录 TTL 太长,DNS 切换很慢——切之前调小 TTL,不是切之后。
  • 旧 host 的 A 记录没删——DNS 在新老 host 之间轮询。
  • Cloudflare SSL 选 “Flexible”——Cloudflare → 源站走 HTTP、源站强制 HTTPS,无限重定向。

FAQ

  • SSL 多久签?: DNS 对了之后一般一小时内。卡几个小时的话,重新核对 DNS 值和 Vercel 给的完全一致。
  • 主域选 apex 还是 www?: 2026 年两个都行。选一个全站 canonical / sitemap 都保持一致。
  • 一个项目能挂多个域名吗?: 能。但要选一个 canonical,避免重复内容 SEO 问题。
  • Vercel 前面挂 Cloudflare 行不行?: 行但有讲究——Vercel 记录上关橙云改灰云,或者 Cloudflare 只做 DNS。
  • 同一个域名挂到 Vercel 没问题,挂到 Firebase 却 “needs setup”。: Vercel 直接从 CNAME / A 记录签发证书;Firebase 需要先单独完成 TXT 所有权验证(域名在 Vercel 能用、Firebase 不行)。

相关阅读

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