先看现象。Next.js 14 的 App Router 项目上线后,Search Console 里 400 多个页面的规范网址都是 http://localhost:3000 开头。代码里每个页面都写了 alternates.canonical,本地预览看着完全正常。
这类报错背后常见的原因有几处,逐个排除就行。根 layout 没配 metadataBase,相对路径按默认的 localhost 解析。另一种情况是canonical 写的是相对路径,没有拼上生产域名。
另外,环境变量 NEXT_PUBLIC_SITE_URL 在构建时没有注入。
少数情况下是CDN 回源改写了 Host 头,服务端渲染拿到内网地址。
先看页面源码里的 canonical
curl -s https://www.example.com/article/1 | grep -o '<link rel="canonical"[^>]*>'
随后在根 layout 补 metadataBase
export const metadata = { metadataBase: new URL('https://www.example.com') };
构建时注入站点地址
NEXT_PUBLIC_SITE_URL=https://www.example.com npm run build
剩下的就是抽查三个模板的输出
curl -s https://www.example.com/ | grep -c 'localhost:3000'
改之前先确认了最近有没有人动过配置,避免白查一遍。
怎么算真的好了,看的是同一批现象。页面源码里的 canonical 全部换成生产域名,网址检查显示规范网址正确,重复组数量下降。
补一句。框架默认值在本地看不出问题,一上线就把 localhost 写进索引,构建环境变量要当成发布必检项。这类问题最好一次改到位,反复小改反而容易把原因搅混。
