结论
一个使用 Next.js + Supabase Auth + Google 登录 的产品上线,不能只把代码部署到 Vercel。完整上线至少要同时处理 4 个地方:
- Vercel:部署项目、绑定域名、配置生产环境变量。
- Cloudflare:把域名 DNS 指向 Vercel。
- Supabase:把 Auth 的 Site URL 和 Redirect URLs 改成正式域名。
- Google Cloud:把正式域名加入 OAuth Client 的 Authorized JavaScript origins。
这篇教程按生产项目的真实顺序写。你可以把域名、项目名、Supabase 项目 ref 替换成自己的。
上线前准备
开始前先确认你已经有这些东西:
1. 一个可以本地运行的 Next.js 项目
2. 一个 Supabase 项目
3. 一个 Vercel 账号
4. 一个 Cloudflare 账号
5. 一个已经购买并托管在 Cloudflare 的域名
6. 如果支持 Google 登录,还需要一个 Google Cloud OAuth Client本文示例用这些占位值:
正式域名
https://your-domain.com
www 域名
https://www.your-domain.com
Supabase 项目 URL
https://your-project-ref.supabase.co
Supabase OAuth Callback URL
https://your-project-ref.supabase.co/auth/v1/callback
网站登录回调地址
https://your-domain.com/auth/callback注意:截图里会出现示例项目名和示例域名。你操作时以自己的项目为准。
第 1 步:本地确认项目可以构建
部署前先在本地跑一次构建:
npm run build如果这里失败,不要先去 Vercel 调。先在本地把 TypeScript、环境变量、路由、依赖问题修好。
常见失败原因:
1. 缺少 NEXT_PUBLIC_SUPABASE_URL
2. 缺少 NEXT_PUBLIC_SUPABASE_ANON_KEY
3. 代码里使用了只能在浏览器执行的 API,但放在了服务端组件里
4. 动态路由缺少必要数据
5. ESLint 或 TypeScript 报错一个 Supabase 项目通常至少需要这两个前端环境变量:
NEXT_PUBLIC_SUPABASE_URL=https://your-project-ref.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-supabase-anon-key如果你的项目会生成 sitemap、邮件链接、OAuth redirect URL,建议再加一个站点 URL:
NEXT_PUBLIC_SITE_URL=https://your-domain.com第 2 步:部署到 Vercel
进入 Vercel Dashboard:
https://vercel.com/dashboard点击:
Add New... -> Project选择你的 GitHub 仓库,导入项目。
如果是 Next.js 项目,Vercel 通常会自动识别:
Framework Preset: Next.js
Build Command: npm run build
Output Directory: 自动
Install Command: npm install首次部署前,在 Environment Variables 填入生产环境变量。
NEXT_PUBLIC_SUPABASE_URL
NEXT_PUBLIC_SUPABASE_ANON_KEY
NEXT_PUBLIC_SITE_URL先部署一次,让项目得到一个 Vercel 默认域名,例如:
https://your-project.vercel.app这个默认域名可以先用于测试,但最终生产配置应切到你的正式域名。
第 3 步:在 Vercel 绑定正式域名
进入 Vercel 项目后,打开:
Project -> Settings -> Domains点击:
Add添加你的根域名:
your-domain.com再添加 www 子域名:
www.your-domain.com添加后,Vercel 会给出 DNS 配置建议。使用 Cloudflare 管理 DNS 时,常见推荐是:
Type: CNAME
Name: @
Value: xxxxx.vercel-dns-xxx.com
Proxy: DNS only
Type: CNAME
Name: www
Value: xxxxx.vercel-dns-xxx.com
Proxy: DNS only也有些项目会看到根域名推荐 A 记录。以 Vercel 当前页面给出的建议为准。

检查点:
1. 根域名已经添加到当前项目
2. www 域名已经添加到当前项目
3. 两个域名最终状态都是 Valid Configuration / Configured Correctly
4. 域名没有被其他 Vercel 项目占用第 4 步:在 Cloudflare 配置 DNS
打开 Cloudflare Dashboard:
https://dash.cloudflare.com进入你的域名,打开:
DNS -> Records如果 Vercel 推荐 CNAME,就添加两条记录:
Type: CNAME
Name: @
Target: Vercel 给你的 CNAME 值
Proxy status: DNS only
TTL: AutoType: CNAME
Name: www
Target: Vercel 给你的 CNAME 值
Proxy status: DNS only
TTL: Auto
这里最容易错的是代理状态。
Vercel 通常要求:
Proxy status: DNS only不要选:
Proxied原因是 Vercel 需要直接校验域名解析和证书签发。上线初期先保持 DNS only,等你明确理解 Vercel 与 Cloudflare 代理、缓存、SSL 模式的关系后,再考虑是否打开代理。
如果你原来已经有冲突记录,先删除旧记录:
A @ -> 旧 IP
A www -> 旧 IP
CNAME www -> 旧平台同一个名称下不能同时存在冲突的 A/CNAME 记录。
第 5 步:等待 Vercel 域名校验通过
回到 Vercel:
Project -> Settings -> Domains等待两个域名变成正常状态。
你也可以用命令检查:
npx vercel domains inspect your-domain.com
npx vercel domains inspect www.your-domain.com或者直接检查 HTTP:
curl -I https://your-domain.com
curl -I https://www.your-domain.com期望结果:
HTTP/2 200
server: Vercel如果刚改完 DNS 没生效,等几分钟再查。DNS 传播不是实时的。
第 6 步:更新 Vercel 生产环境变量
域名可以访问后,进入:
Project -> Settings -> Environment Variables把生产环境的站点 URL 改成正式域名:
NEXT_PUBLIC_SITE_URL=https://your-domain.com
如果你用 Vercel CLI,也可以这样操作:
npx vercel env rm NEXT_PUBLIC_SITE_URL production
printf '%s' 'https://your-domain.com' | npx vercel env add NEXT_PUBLIC_SITE_URL production注意:
1. NEXT_PUBLIC_ 开头的变量会暴露给前端,不能放私钥
2. Supabase anon key 可以放 NEXT_PUBLIC_,service role key 绝对不能放前端
3. 修改环境变量后,必须重新部署才会在生产环境生效重新部署:
npx vercel --prod或者在 Vercel Dashboard 里点 Redeploy。
部署完成后,进入:
Project -> Deployments确认最新生产部署是 Ready / Production。

第 7 步:更新 Supabase Auth URL Configuration
如果项目使用 Supabase Auth,这一步必须做。否则用户登录后可能跳回旧域名、本地域名,或者被 Supabase 拦截。
打开 Supabase:
https://supabase.com/dashboard进入项目后打开:
Authentication -> URL Configuration把 Site URL 改成正式域名:
Site URL
https://your-domain.com在 Redirect URLs 里添加正式登录回调地址:
https://your-domain.com/auth/callback建议保留本地开发地址:
http://localhost:3000/auth/callback如果你还想保留 Vercel 默认域名用于测试,也可以保留:
https://your-project.vercel.app/auth/callback
配置完成后,最终应该类似:
Site URL
https://your-domain.com
Redirect URLs
http://localhost:3000/auth/callback
https://your-project.vercel.app/auth/callback
https://your-domain.com/auth/callback不要把 Google 的 Supabase callback URL 填到这里。这里填的是你网站自己的回调地址。
第 8 步:确认 Supabase Google Provider 已启用
如果你的网站支持 Google 登录,继续打开:
Authentication -> Sign In / Providers找到:
Google确认 Provider 是启用状态,并且 Client ID / Client Secret 已经填好。

在 Google Provider 面板里,Supabase 会提供一个 OAuth Callback URL,格式是:
https://your-project-ref.supabase.co/auth/v1/callback这个地址要填到 Google Cloud 的 Authorized redirect URIs。
第 9 步:更新 Google Cloud OAuth Client
打开 Google Cloud Console:
https://console.cloud.google.com进入:
Google Auth Platform -> 客户端找到你的 Web OAuth Client,进入编辑页。
在:
已获授权的 JavaScript 来源添加正式域名:
https://your-domain.com注意这里不要加路径:
正确
https://your-domain.com
错误
https://your-domain.com/auth/callback在:
已获授权的重定向 URI保持 Supabase callback:
https://your-project-ref.supabase.co/auth/v1/callback
Google OAuth 的关键关系是:
浏览器来源:
https://your-domain.com
Google 回调到 Supabase:
https://your-project-ref.supabase.co/auth/v1/callback
Supabase 再跳回你的网站:
https://your-domain.com/auth/callback不要把这三个地址混在一起。
Google 页面会提示:
设置可能需要 5 分钟到几小时才会生效所以如果刚保存就测试失败,先等几分钟,再重新测试。
第 10 步:检查线上访问
正式域名配置完成后,至少检查这些 URL:
curl -I https://your-domain.com
curl -I https://www.your-domain.com
curl -I https://your-domain.com/login
curl -s https://your-domain.com/robots.txt
curl -s https://your-domain.com/sitemap.xml | head期望结果:
首页返回 200
登录页返回 200
robots.txt 里的 Sitemap 使用正式域名
sitemap.xml 里的 loc 使用正式域名如果 sitemap 里还是旧域名,通常说明:
1. NEXT_PUBLIC_SITE_URL 没改
2. 改了环境变量但没有重新部署
3. 代码里写死了旧域名第 11 步:检查登录注册流程
打开正式站:
https://your-domain.com/login测试邮箱注册:
1. 输入邮箱和密码
2. 点击注册
3. 如果开启邮件确认,检查邮箱是否收到确认邮件
4. 确认后回到网站
5. 检查是否进入用户中心测试邮箱登录:
1. 使用已经注册的邮箱和密码登录
2. 检查是否进入 /account
3. 刷新页面,确认仍然保持登录
4. 退出登录,确认受保护页面不能访问测试 Google 登录:
1. 点击使用 Google 登录
2. 跳转到 Google 账号选择页
3. 授权后回到网站
4. 检查是否进入 /account
5. 在 Supabase Authentication -> Users 里确认用户记录存在Google 授权链路异常时,优先检查:
1. Google Cloud JavaScript origin 是否包含正式域名
2. Google Cloud redirect URI 是否是 Supabase callback
3. Supabase URL Configuration 是否包含正式 /auth/callback
4. 代码里的 redirectTo 是否指向正式域名
5. Vercel 是否已经重新部署第 12 步:生产环境安全检查
上线后做一次最小安全检查。
环境变量:
1. service role key 不允许出现在 NEXT_PUBLIC_ 变量里
2. Vercel token 不要写进仓库
3. .env.local 不要提交到 Git
4. 用过的临时 token 及时撤销Supabase:
1. public 表必须开启 RLS
2. 策略只允许用户读写自己的数据
3. 不要在前端调用 service role key
4. Auth Redirect URLs 不要随便配置通配符Cloudflare:
1. DNS 记录不要保留旧平台冲突记录
2. 初期保持 DNS only
3. 如果开启代理,重新检查 Vercel 证书、跳转和缓存Google OAuth:
1. JavaScript origins 只放可信域名
2. Redirect URIs 只放 Supabase callback
3. 如果仍处于 Testing,需要把测试账号加入测试用户
4. 正式发布给公众用户前,检查 OAuth consent screen 状态常见问题
1. 域名已经能打开,但 Vercel 还提示 DNS change recommended
先看 Vercel 推荐的记录类型和值。如果实际访问已经是 Vercel 200,通常不是致命问题,但建议最终按 Vercel 推荐记录调整。
Cloudflare 支持根域名 CNAME flattening,所以根域名也可以配置成 CNAME 指向 Vercel 推荐值。
2. www 可以打开,根域名打不开
检查 Cloudflare 是否只有 www 记录,缺少 @ 记录。
至少需要:
@ -> Vercel
www -> Vercel3. 登录后跳回旧域名
检查三个地方:
1. Vercel NEXT_PUBLIC_SITE_URL
2. Supabase Site URL
3. Supabase Redirect URLs改完 Vercel 环境变量后必须重新部署。
4. Google 登录提示 redirect_uri_mismatch
说明 Google Cloud 的 Authorized redirect URIs 不匹配。
Supabase Auth 场景下,Google redirect URI 应该是:
https://your-project-ref.supabase.co/auth/v1/callback不是:
https://your-domain.com/auth/callback5. Google 登录提示 origin 不允许
检查 Google Cloud 的 Authorized JavaScript origins。
正式站必须包含:
https://your-domain.com不要带路径,不要写成 /auth/callback。
6. robots.txt 或 sitemap.xml 还是旧域名
检查代码是否使用 NEXT_PUBLIC_SITE_URL 生成站点地址。
然后检查 Vercel Production 环境变量是否已更新,并重新部署。
最终上线清单
上线完成前,逐项确认:
[ ] npm run build 本地通过
[ ] Vercel Production 部署成功
[ ] Vercel 绑定 root 域名
[ ] Vercel 绑定 www 域名
[ ] Cloudflare DNS 指向 Vercel
[ ] Cloudflare 代理状态是 DNS only
[ ] NEXT_PUBLIC_SITE_URL 是正式域名
[ ] Supabase Site URL 是正式域名
[ ] Supabase Redirect URLs 包含正式 /auth/callback
[ ] Google OAuth JavaScript origins 包含正式域名
[ ] Google OAuth redirect URI 是 Supabase callback
[ ] 首页返回 200
[ ] 登录页返回 200
[ ] robots.txt 使用正式域名
[ ] sitemap.xml 使用正式域名
[ ] 邮箱注册可用
[ ] 邮箱登录可用
[ ] Google 登录可用这份清单全部通过后,项目才算完成一次基本可靠的生产上线。