做多语言或多地区站点时,最容易出问题的往往不是翻译质量,而是“谁是谁”没讲清楚。搜索引擎需要知道:这几个地址其实是同一内容的不同语言版本,而不是互相抄袭的重复页面。这个声明主要靠 hreflang、canonical 和语言版本之间的互相链接来完成。配错不会立刻报错,通常表现为某个语言版本长期不被收录,或者搜索结果里给出的版本跟用户所在地不匹配。
先理清三种关系
动手之前,先把站点里的地址分成三类,混在一起是最常见的错误来源:
- 语言版本:同一份内容的不同语言,例如 /zh/ 与 /en/,它们互为替代版本。
- 地区版本:同一种语言面向不同地区,例如 en-US 与 en-GB,差别可能只在货币、联系方式、配送说明。
- 真正不同的页面:主题不一样,只是长得像,这类页面之间不应该声明替代关系。
hreflang 的几个硬性要求
规则本身不复杂,但容错很低:
- 双向声明:A 页面指向 B,B 页面也必须指回 A。只写一边等于没写。
- 自引用:每个页面要把自己也列进去。少了这一条,整套声明容易整体失效。
- 语言代码规范:语言用 ISO 639-1 代码,地区用 ISO 3166-1 Alpha-2,中间用连字符,例如 zh-Hans、en-US、pt-BR。
- 地址可直接访问:指向 404、重定向或需要登录才能打开的地址,等于在给蜘蛛指错路。
- x-default 兜底:没有明确语言匹配时展示哪个版本,建议指向主语言版本或语言选择页,不要让它本身变成一条断链。
URL 结构怎么选
三种常见做法各有取舍,重点是一旦定了就别频繁改:
- 子目录(example.com/en/):维护最简单,权重集中,适合大多数站点。
- 子域名(en.example.com):适合不同语言由不同团队独立运营的情况,但权重是分开积累的。
- 独立域名:一般用于业务目标差异较大的地区站点,成本和管理复杂度最高。
不建议用参数区分语言,例如 ?lang=en。参数地址容易被当成同一页面的变体处理,也会给抓取预算增加不必要的负担。
自查清单
按下面的顺序过一遍,通常十分钟能发现大部分问题:
- 列出所有语言版本,确认每个版本都有对应的一套 URL。
- 随机抽 5 到 10 个页面,检查 hreflang 是否双向、是否包含自引用。
- 检查 x-default 是否指向一个真实可访问的页面。
- 确认每个语言版本的 canonical 指向自己,而不是都指向主语言版本。把所有版本的 canonical 都写成英文页是高频错误,等于主动放弃其他语言版本的收录。
- 检查语言切换器的链接是否正确。切换器是访客和蜘蛛发现其他版本的主要入口,如果它用的是脚本跳转或拼错的地址,其他语言版本就很难被找到。
- 看一遍 Sitemap,确认语言版本之间的对应关系与页面上的声明一致,不要出现两套互相矛盾的说明。
- 抽查渲染后的源代码,确认 hreflang 不是只在运行时由前端脚本插入。
内容本身也要经得起看
技术声明只是告诉搜索引擎“这些是替代版本”,并不能决定哪个版本被展示。如果某个语言版本只是机器翻译的产物,读起来磕磕绊绊,或者产品参数、联系方式还停留在原文,那它在任何场景下都不会有好的表现。
把多语言站点当成几个独立站点来运营:每个版本都需要自己的内容更新节奏、关键词梳理和内部链接,而不是主站内容的镜像目录。
上线之后怎么验证
改完不要只靠感觉。用抓取工具跑一遍代表性地址,观察返回的状态码、canonical 和 hreflang 是否与预期一致;再对照服务器日志,看不同语言版本的蜘蛛访问频率是否明显失衡。如果某个版本长期几乎没有抓取记录,通常说明它在站内缺少入口,或者被某条规则挡住了。
多语言站点的维护成本主要不在搭建阶段,而在后续每一次内容更新时能否让几个版本保持同步。把语言版本的对应关系整理成一张表,新增和下线页面时都过一次这张表,比事后排查省力得多。