/en/、/zh/这种多语言目录应该怎么设计?

先给可以直接抄的结论:语言目录做域名后的第一级,/zh/finance/margin/en/finance/margin 平行存在,每个语言版本的目录结构完全对齐。

不要写成 /finance/zh/margin。那种写法里语言插在内容层级中间,多一个语言就要动一次路由,而且不同语言的目录树很容易长歪——中文版少一个分类,英文版多两篇,hreflang 的对应关系维护起来会变成噩梦。

目录、子域、参数三种方案怎么选

子目录(example.com/zh/:所有语言的权重聚在同一个域名下,新语言上线不需要重新积累域名信任度。代价是部署稍微麻烦一点,但这是绝大多数站该选的方案。

子域(zh.example.com:Google 能处理,但每个子域在一定程度上被当作独立站点,信任度要重新积累。除非技术架构上实在无法共享——比如不同语言由不同团队、不同系统维护——否则没必要。

参数(example.com/page?lang=zh:最不推荐。参数形式的 URL 容易被当成同一页面的变体,抓取优先级低,和 hreflang 配合时也容易出错。

选目录之后还有一件事:默认语言要不要带目录。两种都可行——/ 直接是英文、/zh/ 是中文;或者 /en//zh/ 都带,根路径做语言选择页。我倾向后者,结构对称、路由规则统一,不必为根路径写特例。

hreflang 的写法,三条规则缺一不可

声明写在哪都行——HTML <head>、HTTP 响应头、或者 sitemap——但三种只能选一种。混用的后果是两处声明冲突,Google 会认为信号不可靠,整组放弃。页面数量多的时候放 sitemap 最省事,页面少的时候写进 <head> 更直观。

HTML 里长这样:

html
<link rel="alternate" hreflang="zh-CN" href="https://example.com/zh/finance/margin" />
<link rel="alternate" hreflang="en-US" href="https://example.com/en/finance/margin" />
<link rel="alternate" hreflang="x-default" href="https://example.com/en/finance/margin" />

配套的三条规则:

必须双向回指。 中文页声明了英文页,英文页就必须也声明中文页。单向声明等于没写。这一条在程序化生成时最容易漏——模板里只生成了当前语言的链接,忘了把其他语言的反向声明也生成出来。

每组必须包含自己。 /zh/finance/margin 的那一组里,必须有一条 hreflang="zh-CN" 指向它自己。漏掉自己,整组失效。

x-default 指向语言选择页或默认版本,给那些不匹配任何已声明语言的用户兜底。

语言代码用 ISO 639-1(zh、en、ja),地区代码用 ISO 3166-1 Alpha-2(CN、US、GB),两者用连字符连接。只写 zh 不写地区是合法的,表示"所有中文用户",但和 zh-CNzh-TW 混用时要小心覆盖范围重叠。完整取值规则在 Google Search Central 的国际化文档里。

站点与地区不是一回事,别用 IP 跳转

最具破坏性的做法是"根据访客 IP 自动跳转到对应语言"。爬虫的 IP 通常来自美国,你一跳转,爬虫永远只能抓到英文版,其他语言版本根本进不了索引。

正确做法是让用户落在他请求的那个 URL 上,页面上给一个明显的语言切换入口。想做智能一点,可以在检测到明显不匹配时弹一个提示条,而不是直接 302 跳走。

同样要避免把语言判定写进 Nginx 的 rewrite 规则里——这类规则会同时作用于爬虫,而且一旦写错,排查起来比重写业务代码还麻烦。

翻译深度比目录结构更能决定成败

Omni Calculator 做了 30 多种语言,2026 年 6 月估算访问约 1429 万,那是建立在真正本地化基础上的——不只是界面文案,连单位、数字格式、税法口径都跟着地区走。

Omni Calculator 计算器分类页截图
Omni Calculator 计算器分类页截图

Omni Calculator 首页连 Sports 都单独分类,111 个计算器对应各类赛事和成绩换算。

反面参照是 TinyWow:流量里美国占 20.17%、印度 14.63%、英国 3.22%,前三名全是英语地区,但它并没有因此去做几十种语言。工具站的通用性足够高时,单一语言照样能吃下多地区流量。

结构化数据里的语言也要跟着变

JSON-LD 里的 inLanguage 字段必须和该页面语言一致,namedescription 也要用对应语言的值。只翻译正文、结构化数据还是英文,会让 Google 认为标记与页面不符。

多语言站我习惯把每个语言的页面数据放在 SQLite 的同一张表里,用 lang 字段区分、i18n_group 标记互为翻译版本的记录,构建时按 group 分组输出 hreflang 组和各语言的 sitemap。一份数据出全部产物,不会出现某个语言的链接漏生成、或者单向声明的情况。


Omni Calculator 30+ 语言、2026 年 6 月访问约 1429 万(Semrush 估算);TinyWow 地区分布为第三方估算(2026 年上半年)。