十个语言版本只有三个被收录:外贸站 hreflang 与 x-default 的配置实战
上个月帮深圳一个做汽配出口的朋友看站,姑且叫他老周。他的独立站做了 10 个语言版本,英、德、法、西、意、日全铺了,结果 Google Search Console 里数来数去只有 3 个语言目录有像样的收录,德语版收录量长期停在两位数。更离谱的是,德国用户在 Google 搜他们的产品词,排前面的经常是英语页面。老周原话:"我花十几万翻译的页面,Google 好像根本不知道它们存在。"
排查下来,问题不在内容,也不在外链,就在 head 里那几行 hreflang——他写错了一个参数,而且没有 x-default。改完之后六周,收录恢复到 9 个语言版本,这个后面细说。这篇文章把 hreflang 的三种实现方式、常见错配和我踩过的坑一次讲完,主体是传统搜索引擎(Google、Bing、百度)视角下的多语言收录与规范化(Canonicalization),不走 AI 引用那套话题。
hreflang 的工作机制:先搞清楚它在解决什么问题
很多人把 hreflang 当成"排名技巧",这个理解方向就偏了。它本质上是一个信号,不是指令。

搜索引擎处理一个多语言站的流程大概是这样的:爬虫抓取页面 → 做规范化判断(这一堆 URL 里哪个是"正主")→ 决定索引哪些 → 按用户语言和地区排出来。多语言站最怕的就是第二步出错:/de/ 和 /en/ 内容结构高度相似,如果页面之间没有互相声明关系,Google 可能把德语版当成英语版的重复内容,直接从索引里挤掉。这就是老周 10 个版本只剩 3 个收录的根本原因——不是页面质量不行,是页面之间的关系没交代清楚。
flowchart TD
A[爬虫抓取 /de/product] --> B{发现规范化信号}
B -->|有 hreflang 互指 + 正确 canonical| C[确认这是德语独立版本]
C --> D[进入索引 参与德语区排序]
B -->|无 hreflang 或互指断裂| E[疑似英语版的重复内容]
E --> F[规范化到英语版 德语页面被挤出索引]
还有一个容易混淆的点:hreflang 和 canonical(规范链接)是配合关系,不是替代关系。每个语言版本的 canonical 都应该指向自己,然后再用 hreflang 互相声明"我们是同一个内容的不同语言版本"。我见过不少人为了让页面"聚焦权重",把所有语言版的 canonical 都指向英语版——这在搜索引擎看来等于亲口承认"德语版就是重复内容",收录直接归零。Bing 官方也多次说明它参考 hreflang 但同样看重 canonical 的一致性,百度目前对 hreflang 的支持比较有限,中文多语言站更多要靠目录结构和内容差异化来解决。
另外说一句抓取预算(Crawl Budget)。老周这种 10 语言 × 5000 SKU 的站,URL 总量 5 万起,其中大量页面因为规范化混乱被反复抓取又反复丢弃。把 hreflang 理顺之后,爬虫不用再猜来猜去,抓取效率肉眼可见地好了起来。
三种实现方式怎么选
hreflang 有三种落地方式,各有各的适用场景。我们最终选的是 sitemap 方式,理由后面讲。
| 实现方式 | 适用场景 | 优点 | 坑 |
|---|---|---|---|
| HTML link 标签 | 页面数量少、模板统一的中小站 | 直观、改起来快 | 5000 页以上维护成本爆炸,模板改漏一处全站完蛋 |
| HTTP 响应头 | PDF、图片等非 HTML 资源的多语言版本 | 不占 HTML 体积 | 运维要动 Nginx/CDN 配置,排错看不见摸不着 |
| XML Sitemap | 大站、多语言目录结构清晰 | 集中管理,一处改完全站生效,GSC 直接可验证 | 生成逻辑要自己写,URL 拼错不容易发现 |
环境:Nginx 1.24 / Node 20 生成 sitemap。先看 link 标签写法,这是最常见的:
<head>
<!-- 每个语言版本都要完整列出所有版本,包括自己 -->
<link rel="alternate" hreflang="en" href="https://example.com/en/product" />
<link rel="alternate" hreflang="de" href="https://example.com/de/product" />
<link rel="alternate" hreflang="de-AT" href="https://example.com/de-at/product" />
<!-- x-default 指向语言选择页或默认版,后面细说 -->
<link rel="alternate" hreflang="x-default" href="https://example.com/product" />
<!-- canonical 指向自己,千万别指到别的语言版 -->
<link rel="canonical" href="https://example.com/de/product" />
</head>
HTTP 头方式适合非 HTML 资源,比如同一份产品手册有英德两个 PDF:
# Nginx 配置:给德语版 PDF 加 hreflang 响应头
location /manuals/de/ {
add_header Link '<https://example.com/manuals/de/product.pdf>;
rel="alternate"; hreflang="de"' always;
# 注意 always 参数,不加的话 4xx/5xx 响应不带这个头
# 这个头只写在德语版 PDF 上,英语版要另配一个 location 块
}
sitemap 方式的写法,用 xhtml:link 扩展:
<url>
<loc>https://example.com/de/product</loc>
<!-- 这条 URL 自己的版本也要列,漏了自己整组作废 -->
<xhtml:link rel="alternate" hreflang="de" href="https://example.com/de/product"/>
<xhtml:link rel="alternate" hreflang="en" href="https://example.com/en/product"/>
<!-- 兜底版本,用户语言不匹配时落到这里 -->
<xhtml:link rel="alternate" hreflang="x-default" href="https://example.com/product"/>
</url>
为什么大站选 sitemap?一是集中,5000 个页面的互指关系在一个文件里就能核对;二是不怕前端模板重构时把 head 改坏;三是提交到 GSC 后能看到明确的处理状态。代价是要写生成逻辑,并且每次发布新页面都要重新生成。
我们踩过的五个错配
这部分是最值钱的,都是实际发生过、GSC 里能看到后果的问题。
| 错配 | 后果 | 发现方式 |
|---|---|---|
| 互指不完整:A 指了 B,B 忘了指回 A | Google 直接忽略这组 hreflang | GSC 国际定位报告里的 hreflang 错误数 |
| hreflang 指向 404 或重定向 | 整组注解作废 | Screaming Frog 爬一遍全站 |
语言代码写错:de-DE 写成 de_de 或 de-DE-DE |
该版本不参与对应地区排序 | 手工 review + 正则扫 sitemap |
| 所有语言 canonical 指向英语版 | 其他语言收录归零 | GSC 页面索引报告"重复网页,Google 选择了不同规范网页" |
| 缺 x-default | 无匹配语言的用户被硬塞一个随机版本 | 用户反馈,德国客户收到日语页面 |
互指不完整这条要特别展开。hreflang 是一个双向承诺:你说 /de/ 是 /en/ 的德语版,那 /en/ 的注解列表里必须有 /de/,两边缺席任何一边,整组关系作废。老周的站就是发布脚本只在德语模板里注入了注解,英语模板的注入逻辑坏了半年没人发现。2026 年 7 月 24 日我们跑完修复脚本当晚,GSC 国际定位报告里的"错误"从 47000 多条开始往下掉。
重定向那个坑也值得一提:老站 /de/ 迁到 /de-de/ 之后,sitemap 里的 hreflang 有三周一直指向旧 URL 的 301。Google 对指向重定向的 hreflang 处理很谨慎,那段时间德语收录一直是锯齿状波动,改成直连最终 URL 才稳住。
还有个没完全解决的问题说一下:意大利语版内容当时是机翻后人工抽查的,改完 hreflang 收录上来了,但意大利语词的排名始终上不去。这说明 hreflang 只解决"让你进考场",考不考得过还是看内容本身,别指望注解能救烂页面。
收录恢复:自建监测口径下的数据
强调一下口径:下面所有数据来自我们自己的监测(GSC 导出 + 每周固定时间用同一批 200 个关键词手工查排名),不是任何第三方工具的统计,采样方法也粗糙,看趋势就好。
时间线是这样的:2026 年 6 月 30 日完成全部 10 个语言版本的 hreflang + x-default 修复并提交新 sitemap;第 7 天 GSC 里 5 个语言目录的"已编入索引"开始抬头;第 42 天(8 月 11 日),10 个版本里 9 个收录破千,剩下一个芬兰语版因为当时站内芬兰语内容只有 80 多个页面,属于内容量不足而不是收录问题。
flowchart LR
A[6月30日 修复上线] --> B[第7天 5个语言目录收录抬头]
B --> C[第21天 德语错误数清零]
C --> D[第42天 9个版本收录破千]
关键词层面,德语区那批 200 个监测词里,搜出来命中德语页面的比例从修复前的三成多涨到七成上下。这个数字对我们的价值很直接:德国站独立域名的转化询盘在 8 月当月比 6 月多了差不多四成,虽然里面有一部分是旺季因素,没法完全剥离,但方向是对的。
一个忠告:别在改完 hreflang 的第二天就看数据。Google 重新抓取、重新评估规范化、调整索引,这个链条走完通常要两到六周,中途的波动全是噪音。我第一次做这种修复时盯着 GSC 刷了一周,被一次正常的收录下降吓得回滚了配置,纯属白费劲。
x-default 该指向哪
x-default 是给"语言和地区都对不上号"的用户准备的兜底,比如一个用阿拉伯语的访客搜到了你的站。它的指向有三种流派:
- 指向语言选择页(根路径放一个让用户选语言的页面);
- 指向默认语言版(通常是英语);
- 指向基于 IP/Accept-Language 自动跳转的入口。
我们给老周的站用的是第二种,理由是第一种的选择页对 SEO 没有独立价值还多一层跳转,第三种自动跳转会干扰 Googlebot 抓取(Googlebot 主要从美国出没,IP 判断会把它当成美国用户),搞不好把爬虫也跳晕了。谷歌官方文档对自动重定向的态度一直是"谨慎",Bing 更是明确建议不要做基于 IP 的强制跳转。
# 老周站的方案:x-default 直接给英语版,不做 IP 跳转
map $http_accept_language $lang_redirect {
default ""; # 无法识别语言就不跳
~^de de; # 德语用户跳德语版
}
补充一个细节:如果做了 Accept-Language 软跳转,记得用 302 而不是 301,并且给 Googlebot 放行不跳转。这个坑是阿 May 踩的,她当时上了 301 硬跳,一周内 GSC 抓取统计直接腰斩。
收尾说两句 GEO
hreflang 理顺之后还有个意外收获:站点的多语言内容在 AI 搜索答案里被引用的频率也上来了。逻辑不难理解——生成式引擎优化(Generative Engine Optimization, GEO)同样需要清晰的页面关系信号,AI 引擎在检索时也需要知道"哪个版本对应哪种语言的用户",混乱的规范化对传统引擎和 AI 引擎都是减分项。所以这套功夫不会白做。
参考与延伸
- Google Search Central:告诉 Google 您网页的本地化版本
- Google Search Central:整合重复网址
- web.dev:国际化与本地化最佳实践
- MDN:link rel=alternate 与 hreflang
hreflang · x-default · 多语言收录 · Canonical · Google Search Console · 网站优化 · SEO