你的多语言网站,很可能只有一种语言被收录
在同一个 URL 上用 JavaScript 切换语言,是让六份译文对搜索引擎隐形的最常见做法。这里讲的是究竟什么会被收录,以及如何组织一个静态站点使之不发生。
我们经常见到这样的情形:一家公司把网站翻译成六种语言,做了语言切换器,然后从任何新市场都看不到流量。译文质量很好。没有人找得到它们。
原因几乎总是同一个,而且属于架构问题,不是内容问题。
搜索引擎收录的是 URL,不是应用状态
如果你的语言切换器只是替换页面上的文字,并把选择记在 localStorage 或 cookie 里,那么所有语言共用一个 URL。
爬虫请求那个 URL,拿到 HTML 里烘好的那一种语言,然后收录它。从搜索的角度看,你另外六份译文并不存在。没有第二个 URL 可以排名,没有独立的标题,没有独立的描述。
这不是需要绕过的爬虫限制。URL 就是收录的单位。一个 URL 意味着一份被收录的文档。
测试很简单:你能发给别人一个链接,让它以日语打开你的页面吗?如果不能,Google 也没法收录一个日语版本。
客户端切换在什么场景下没问题
也该对这个做法公平一点,因为它并非总是错的。当页面本身不是人们通过其正文内容找到的东西时,客户端切换完全合理:
- 登录之后的应用界面
- 仪表盘和内部工具
- 流量来自广告、转介或口碑的小型宣传站
一旦你想要这些语言带来的自然搜索流量,它就成了问题。内容营销、文档和博客恰恰属于这种情况。
给每种语言一个真正的 URL
三种常见结构,搜索引擎都接受:
| 结构 | 示例 | 说明 |
|---|---|---|
| 子目录 | example.com/ja/page | 最简单。继承域名权重。通常是正确的默认选项。 |
| 子域名 | ja.example.com/page | 可行,但要多管 DNS 和证书。 |
| 独立域名 | example.jp/page | 本地信号最强,成本最高。每个域名各自积累权重。 |
对大多数团队:子目录。你得到一个不断积累权重的域名,而且不需要额外的基础设施工作。
然后告诉搜索引擎这些页面彼此相关
仅仅拆开 URL 会带来新的风险:七个说同一件事的页面可能看起来像重复内容。hreflang 就是你用来说"这些是同一个页面的不同语言版本,请展示正确的那个"的方式。
在每一个版本上,列出所有版本,包括它自己:
<link rel="alternate" hreflang="en" href="https://example.com/en/page">
<link rel="alternate" hreflang="vi" href="https://example.com/vi/page">
<link rel="alternate" hreflang="ja" href="https://example.com/ja/page">
<link rel="alternate" hreflang="x-default" href="https://example.com/en/page">
再加上每个页面指向自身的 canonical:
<link rel="canonical" href="https://example.com/ja/page">
五个会毁掉它的错误
- 缺少回链。
hreflang必须互相对应。如果英文页指向日文页,而日文页不指回来,这一对就会被忽略。这是最常见的失败,遥遥领先。 - canonical 指向了另一种语言。 一个日文页面的 canonical 指向英文 URL,等于在指示搜索引擎丢弃它。canonical 必须指向自身。
- 把语言和地区搞混。
hreflang="ja"是日语。hreflang="ja-JP"是专供日本的日语。除非你确实有按地区区分的版本,否则用不带地区的语言码;没必要的收窄会让你损失其他地方的读者。 - 用错代码。 地区子标签是国家代码,不是语言代码。英式英语是
en-GB,不是en-UK。对中文来说,文字比国家更重要:zh-Hans和zh-Hant。 - 用了相对 URL。
hreflang和 canonical 需要带协议和域名的绝对 URL。
连 slug 一起翻译
一个容易拿到却常被跳过的收益:URL 里的词是该语言中的相关性信号。如果你的越南语页面在 /vi/how-to-look-up-a-character,那这个 URL 在越南语里没有贡献任何东西。
翻译 slug,并保留一个稳定的内部标识符来配对各个版本。我们这个博客正是这样组织的:每篇文章有一个永不改变的 id,以及一个随语言变化的 slug。
不要按 IP 自动跳转
很诱人,而且会造成真实的损害。如果你检测访客所在国家并强制跳转:
- 爬虫大多从一个国家发起请求,可能只看得到一个版本。
- 你覆盖了那些有意选择别的语言的人。在日本的很多人就是想读英文。
建议,不要强制。给一个提示条,让切换器保持可见,让 URL 决定内容。
静态站点做这件事很容易
上述没有一项需要 CMS 或服务器。在构建时为每个页面的每种语言各生成一个 HTML 文件,把正确的标签烘进去,然后上传整个文件夹。产物是纯静态文件;智能都在你部署前运行的那个生成器里。
我们这个博客就是这么做的:内容存在每篇文章每种语言一个文件里,一个小脚本生成带 hreflang、canonical、JSON-LD 和分语言 sitemap 条目的 HTML,而站点本身仍然是一堆静态文件,完全没有后端。
一份检查清单
- 每种语言都有自己的、可以发给别人的 URL
- 每个页面在
hreflang中列出所有语言,包括自身,且双向对应 - 为无法匹配的访客提供
x-default - 每个页面的 canonical 指向自身
- slug 已翻译,内部用稳定的 id 配对
- sitemap 列出每个语言 URL 及其备选版本
html lang与实际内容一致- 没有基于 IP 的强制跳转