早在使用 WordPress 时,我就在琢磨用什么样的方式实现网站多语言。WordPress.org 本身的多语言支持很不错,但用 WordPress 构建多语言内容体系并不轻松。后来转用 Grav,从中学到了一种很好的方式。当我开始自己写网站程序时,就决心实现一个好用、合理的方案。本文记录其中一些设计细节。

要撰写多语言内容

语言承载着文化;选择一种语言,也就选择了内容能够抵达的读者与语境。有识之士早在十几年前就开始写英文文章了(awflasher 的博客)。甚至一些人搞垃圾农场站群的人,都在做英文内容。某些话题,用英文确实更容易找到受众;另一些内容则应当优先用中文写好。重点不是把所有文章都翻译一遍,而是在确有读者的语言中提供经过校对、真正有用的原生版本。

如今的时代,即使英文不是很好,也不耽误与英文世界交流。早年可以使用翻译软件,用多家软件在源语言和目标语言之间互译,充做校对;近年又可以使用更懂人话的 AI。同时,撰写英文内容之后进行人工阅读校对,也是一个极佳的学习英文的途径1。比如 pigleo 在《人人都能写英文博客》中提到,因自己的文章被盗译为英文,于是开始使用软件辅助进行英文写作。

鉴于中文互联网正在逐渐崩塌2,进而导致文化交流受限3,撰写多语言内容有助于文化输入输出,做文化搬运工——或者直观点说:老乡,写英文能有更多的流量!

多语言网站实现

当然可以选择做一个独立的英文站,但这还不够 International。WordPress.org 建立了不同语言的分站,来给用户提供帮助和支持,其中有论坛板块。而论坛中的发帖的内容,一般都只有单独一个语言的版本。如果你是自己写文章,则网站上的每一篇内容都有可能有多个语言的版本,这种情况每种语言建一个独立站,就容易造成同一内容的多语言版本失去了关联性。

有作者在页面提供翻译功能,或者读者会使用翻译软件(如:沉浸式翻译),但这不是原生内容:读者无法预先判断译文质量,只能多彼一举地用 API 再翻译一遍,搜索引擎也无法把它当作独立、可维护的语言版本。最好还是手动创建多语言内容;哪怕全是 AI 翻译的,耗一点精力校对一遍,也是极好的。

所以,我对多语言网站的理解是,内容和 UI 都原生支持多语言版本,多种语言浏览体验一致,内容及质量一致。本质上是同一个网站,虽然可以使用子域名,甚至不同域名,但并不是我预期中的形态——所以 WordPress 的多站点模式并不在讨论的范围内。

我用过 qtranslate-x 插件来给 WordPress 实现多语言。这个插件更新缓慢,且使用在数据库字段中加入分隔符来存储多语言文本,是一种对 WordPress 不天然支持多语言内容的现状的一种妥协实现方案。在使用和迁移时,常会遇到一些麻烦。我也不太想尝试 WPML。而 Grav 是基于文件的,如果你的中文版本内容的文件名是 item.zh.md,那么在同级目录创建 item.en.md 就算建立了对应的英文内容。这一设计非常直观和自由。

不过 Grav 也有一些小缺陷,站点配置只有一套,比如网站名称,只支持一个语言版本注1。所以我也使用了极为相似的处理方式,在此基础上,可以实现更精细的规划。

内容的规划

你写了一篇文章,来赞美中国大陆的 App 备案制度,你会考虑创建一个英文版本吗?你写了一篇抨击特朗普的长文,你会创建一个台湾正体的版本吗?你写了一篇影评,使用了很多日语中的动漫梗来讽刺,你会考虑做一个德文版本吗?

不做独立站、选择做多语言网站,并不意味着每一篇内容都是雷同的翻译。你可以自由选择为哪些文章提供哪些语言版本;甚至,不同版本也可以基于读者的知识背景,补充不同的解释、示例或行动建议,额外表达迎合其语言文化的营销内容,随您的便。

URL 设计

多个语言的内容挤在一个网站,如何设计 URL 呢?像 Google.com 一样使用 URL Search Param 在 URL 中加入 ?lang=zh-CN?或者让访问者选择一种语言,存在 Cookie 里?还是使用 /en/post-slug/ 这种?

有时浏览一些英文文章,半懂不懂,翻译软件的质量也堪忧;此时若在页面中瞥见几个汉字,便会去寻找中文版本,却往往徒劳无果。若已有多语言版本,应当让读者能发现它。请求头中的 Accept-Language 适合选择初始 UI 语言或回退语言;而内容的语言版本仍应有稳定、可分享的显式 URL。有时遇到纯俄文、纯德文网站,找到语言切换按钮都是一种挑战,这正是应当避免的体验。

所以,我的网站实现了:

  • UI 语言与内容语言分离
  • 默认 URL 选择合适的初始语言或回退语言
  • URL 中包含语言时,展示明确的对应内容版本

除了内容之外,一些页面上的元素也应与语言联动,比如简体中文版本可能需要显示ICP备案号、公网安备案号、出版物经营许可证;欧洲语种可能需要显示 Cookie 隐私选项,点击接受就隐藏提示,点击拒绝就跳转到 Google。

英文用户访问本文的路径 /website-multilingual-design-details/,并不会根据访问者的语言跳转到 /en/website-multilingual-design-details/,仍留在这个页面,UI 显示为英文,内容也显示英文(如果有提供的话)。

而当你访问指定的语言版本的路径,则内容切换为对应版本,而 UI 语言仍然取决于访问者的浏览器设置。

跳转?

我的建议是不要跳转。

URL中文浏览器英文浏览器
/aboutUI 中文,内容中文UI 英文,内容英文
/en/aboutUI 中文,内容英文UI 英文,内容英文
/zh/aboutUI 中文,内容中文UI 英文,内容中文

我认为 UI 语言应当永远跟随用户的选择(Cookie 以及浏览器语言),而 URL 中的 locale 是访问者对内容的预期。当然,UI语言可以默认与内容统一,不过最好能加一个语言提示。

内容语言提示

如果一位非英文用户通过 Google 或社媒链接进入含英文语言路径的 URL,网站应当能够识别内容语言与访问者首选语言不一致。在页面最上方提示当前内容语言和可用版本,让读者自主切换,做到宾至如归;在文章结尾列出全部原生版本,也能方便读者学外语帮忙校对。

其他细节

最重要的 URL 方案确定了,其他的细节几乎是水到渠成。比如语言回退:如果浏览器的首选语言是 en-US,网站可以提供其支持的 en;如果是 zh-CN,也可以将 zh-HK 的内容来勉强应对一下。Grav 中还有一个巧妙的设计,可为一篇文章禁用某个语言:只需创建这个语言的内容,并标记为删除即可。

UI 语言切换

在页尾,提供所有 UI 语言版本,读者可以自由切换;如果有对应的内容版本,内容也会随之切换。这样,即使是默认英语的 Tor 浏览器,也能通过点击 Отправить 按钮来发 Spam 啦。

混合语言内容

通过为 html 标签添加属性 lang="ru" 来标记这是一段俄文。比如前一节中的 html 是 <code lang="ru">Отправить</code>

媒体资源的多语言

如果你使用了含文字的图片,除了在 item.en.mditem.zh.md 文件中引入两个不同链接之外,还可以创建 image.en.pngimage.zh.png 两个文件,再使用 ![](image.png) 引用。此时 URL /image.png 可以通过 Accept-Language 头协商不同语言的资源(没错,Accep-Language 头就是这样用的);不过要正确设置缓存的 Vary,否则更适合使用显式的资源 URL,以便稳定分享和缓存。

RSS

时至今日,还有人怀念 Google Reader。我为 RSS 也实现了自动语言功能。遗憾的是,我尚未发现哪家阅读器的机器人能够传递正确的语言头,并跟随 Atom 文件中的候选语言;于是也支持 /en/feed/ 这种链接来专门订阅英文内容。

SEO

不使用发布平台的坏处之一,就是要自己处理 SEO。Google 为多语言网站提供了很好的指引:等价的语言版本应通过相互指向的 hreflang 关联起来,并且每个版本都要包含自己;只有确实面向未匹配语言用户的通用落地页,才适合使用 hreflang="x-default"4。只要正文经过真实翻译或本地化,语言版本并不会因讨论同一主题而被视为重复内容。

不要只依赖 hreflang。每个语言页面都应拥有稳定、可抓取的 URL、清晰的语言标识和有用的内部链接;canonical 应指向该页面自身。若同时在 Sitemap 中声明语言版本,也要与 HTML 中的标注保持一致。基于文件的文章系统还能为每一种语言单独撰写标题、摘要和元数据——这比堆砌 keywords 更重要。

以及在 robots.txt 中让“更懂中文”的百度专注于中文:

User-Agent: Baiduspider
Disallow: /en/

锚点链接

甚至我还考虑到了锚点链接。默认情况下,Markdown 的 heading 插件会将中文版本中本节标题的 id 指定为 锚点链接;若中文用户分享了无语言路径的带锚点链接,英文用户就无法定位到这一节。理论上,为 Markdown 加入属性支持,并在所有语言中用 {#anchor-link} 指定统一 id 即可。大概是过度设计了,根本不会有这种情况发生……

评论系统语言

又是一个过度的设计。不过评论系统在这种情况下,的确棘手。我选择记录下评论发生时的内容语言和 UI 语言,可以用来按语言分组展示评论,以及选择评论通知邮件的语言。

结语

经过不断改进,目前已经小有成效。曾有人指出我的 RSS 出现 BUG,语言内容混乱(诚意感谢这位朋友)。以及,开始有英文和俄文的 Spam 评论了。“英特纳雄耐尔”,就一定要实现!


注释

  1. 在 Grav 中,可以创建一个隐藏的内容页,用来存储站点配置的多语言版本,但这种方式需要使用支持此功能的定制主题。

参考

  1. Dallas Lu. …原始文章是你自己写的,这个理解程度是他人作品所不能比的。整个过程既有输出的强化练习,又有高效地学习吸收…. 𝕏. 2024-05-01.

  2. 何加盐. 中文互联网正在加速崩塌. cnBeta. 2024-05-23. 首发于微信公众号.

  3. 大毛. 我们正在目睹中国文明的孤岛化. 积薪. 2024-08-13.

  4. Google Search Central. Tell Google about localized versions of your page. Accessed 2026-09-04.