本地化 URL 会搞坏 hreflang,我们只保留一个英文 slug
多语言站点上大多数 hreflang 问题并不是 hreflang 的问题,而是 slug 的问题。如果你在翻译页面之外还翻译 URL,那么每一次重命名、每一次重定向、每一处缺失的翻译,都会变成语言图谱悄悄崩掉的一条路径,而且只发生在没人盯着的那一小部分页面上。
这个网站以四种语言运行,而我们刻意不翻译 slug。AI 可见性的德语页面在 /de/services/ai-visibility/,而不是某个德语路径下。这是一个有真实代价的真实取舍,我们认为对多数团队来说这个取舍是对的。下面是理由,以及代价。
在做多市场站点,却不确定爬虫在每种语言下实际看到什么?
运行免费检查器hreflang 实际要求的是什么
这份约定比工具让人以为的更简单。同一语言集合里的每个页面,都必须指向其他所有版本,包括它自己,而且每一个指向都必须被它所指向的那个页面反向返回。自引用的 hreflang 是正确且必需的,不是可以优化掉的冗余。
正是这条互指要求让本地化 slug 变得昂贵。用一个 slug 时,你只需要知道语言前缀。用翻译过的 slug 时,你需要一张正确且最新的对应表,把每个文档的四个不同字符串关联起来,而且它必须活过任何人做的每一次编辑。
本地化 slug 造成的四种失败
| 失败 | 成因 | 症状 |
|---|---|---|
| 互指断裂 | 某个语言的 slug 被重命名,其他语言仍指向旧字符串 | 语言簇裂成两个,而两边看起来都像权威版本 |
| hreflang 指向重定向 | 标注指向重命名之前的 URL,那个 URL 现在返回 301 | 标注被打折处理,页面之间变成竞争而不是归组 |
| 部分翻译 | 某个语言还没有这个文档的版本 | 要么是一个死指针,要么是一处静默的缺口,取决于循环是怎么写的 |
| 路径冲突 | 两个英文文档翻译成了目标语言里同一个 slug | 一个页面覆盖另一个,通常是客户先发现的 |
这些没有一个是解决不了的。它们都是按文档发生的,而这正是问题所在:它们只出现在少数页面上而不是全站,所以抽查看起来是干净的。
只用一个 slug 能换到什么
如果 slug 与语言无关,语言图谱就变成了路径前缀的函数。模板可以只依据语言列表和页面自己的文件名生成每一个 hreflang 指向,没有对应表需要维护,也没有东西可以失去同步。互指从需要你去核查的事,变成了结构上必然成立的事。
它也让相邻的检查变得便宜。一旦一个文档的每个语言版本共用同一个 slug,"这个文档是不是每种语言都翻译了" 就是一次基于文件名的集合比较。我们把这一点写进了构建:一个脚本断言四种语言在每个数据文件里包含相同的条目集合,另一个比较各语言内容是否出现漂移。这两件事之所以可能,只因为标识符是共用的。
同一个特性也帮到了非搜索引擎的机器。拿到你英文 URL 的智能体,可以按规则推出德语 URL。再配合每条路由一份 Markdown 镜像,就意味着每个文档、每种语言都有一个可预测的地址,中间不需要查表这一步。
诚实的代价
除英文之外的每种语言,你都失去了 URL 里的关键词。对于一个用德语短语搜索的德国买家来说,德语 slug 是一个不大但真实的相关性与点击信号,而我们选择了不要它。
我们接受这一点有三个理由。相比标题、各级标题和正文,URL 里的关键词是很弱的信号,而那三者都是完整翻译的。它避免的失败是静默且会累积的,而它付出的收益是小而可衡量的。而在一个答案引擎和搜索引擎同样重要的站点上,一个可预测的地址比路径里的一个关键词更值钱。
如果你的生意主要是单一市场里的本地语言搜索,而且只有二十几个页面,那就翻译 slug 吧。对应关系小到可以靠人工保持正确。这里讨论的是四种语言、几百条路由的情形,在那种规模上没人能靠人工把对应表维持正确。
迁移时不要丢掉已有的页面
如果你已经在用本地化 slug,这件事既不紧急,也不免费。真要做的时候:
- 选定英文 slug 作为规范形式,并从此保持稳定。你现在做的这次重命名,应该是最后一次。
- 把每个本地化 slug 永久 301 到它。这些重定向就留在那里;没有任何好理由去删掉它们。
- 从语言列表生成 hreflang,而不是从一张表生成,并确认每个页面都返回自引用。
- 重新提交 sitemap 并通知 IndexNow 端点,让改动在几天内而不是几个月内被收录。
- 检查内部链接是否直接指向新 slug,而不是绕经重定向,因为一个满是内部 301 的站点本身就是一个慢性问题。
第五步是最容易被跳过的。一个只能从你自己的导航到达的重定向,是一个你永远不会发现它出错了的重定向。
常见问题
URL slug 该为每种语言翻译吗?
自引用的 hreflang 标签是必需的吗?
英文 slug 会影响本地排名吗?
如果某个页面还没有翻译成所有语言怎么办?
怎么防止各语言的翻译逐渐脱节?
旧的本地化 URL 需要一直可用吗?
最终思考
翻译 URL,等于给一个本来不需要对应表的系统按文档加了一张对应表,而表里的每一条都是语言图谱静默断裂的一次机会。
保留一个与语言无关的 slug,把语言放进路径前缀,从语言列表生成 hreflang,并在构建里守住翻译一致性。你放弃的是一个较弱的关键词信号,换掉的是一整类静默失败。
