KEEL · 龙骨 · A CURRICULUM FOR THE AI ERA

06 · 国际化与多区域:hreflang 的完整语义 — keel 龙骨

本章目标:把 hreflang 从"加几行标签"讲成一套可验证、可排错的多区域方案。 验收标准:语言区域映射双向自洽、无回链错误、canonical 与 sitemap 策略一致。

本章目标:把 hreflang 从"加几行标签"讲成一套可验证、可排错的多区域方案。
验收标准:语言区域映射双向自洽、无回链错误、canonical 与 sitemap 策略一致。

为什么这是深水区:hreflang 的规则看似简单,但错误率极高——因为它要求双向对称,任何一侧漏写都会整组失效。而且它常与 canonical 打架。这一章把语义、矩阵与验证方法一次讲透。


一、hreflang 要解决什么

同一内容有多个语言/地区版本时,用户该看到哪个?hreflang 就是给搜索引擎的"版本路由表"。

<link rel="alternate" hreflang="zh-Hans" href="https://www.xxxxxx.cn/learning/" />
<link rel="alternate" hreflang="en" href="https://www.xxxxxx.cn/en/learning/" />
<link rel="alternate" hreflang="x-default" href="https://www.xxxxxx.cn/learning/" />
值 含义
zh-Hans 简体中文(语言+书写系统)
en-US 美式英语(语言+地区)
x-default 默认/兜底版本(无匹配语言时)

二、三条硬性语义

  1. 必须双向自洽:A 声明指向 B,则 B 必须声明指回 A。单向声明会被忽略。
  2. 必须互相引用,含自身:每个版本都要列出包括自己在内的所有版本。
  3. URL 必须是绝对地址,且是规范的、可索引的终址(不是 301 前的地址)。
❌ 错误:只有 zh 页声明指向 en 页,en 页没指回
✅ 正确:zh 和 en 两页都列出 {zh, en, x-default} 三条

三、常见错误矩阵

错误 症状 结果
单向声明 只有一侧有 hreflang 整组被忽略
遗漏自身 自己不在列表里 该版本不受益
指向 301 地址 href 是重定向前的 URL 无法确认映射
语言代码错误 用 zh-CN 当地区(应结合规范) 可能不被识别
x-default 缺失 无兜底版本 无匹配用户落到哪不确定
hreflang 与 canonical 冲突 canonical 指向另一语言版本 版本被合并
用 JS 注入 第一波看不到 不生效
只在 sitemap、漏了 head 两处不一致 混乱

最容易致命的组合:hreflang 指向 X,canonical 却指向 Y。这等于同时说"我是 X 的替代"和"我的规范版本是 Y",自相矛盾。正确做法:每个语言版本的 canonical 指向自己,用 hreflang 表达替代关系。


四、canonical 与 sitemap 的策略

场景 canonical hreflang
各语言独立内容 各自指向自己 互相引用全部版本
地区变体(en-US/en-GB) 各自指向自己 互相引用 + x-default
语言版本是机器翻译、质量低 指向主语言版本 建议不声明,或 noindex

多语言 sitemap 的两条路线:

<!-- 路线 A:在 sitemap 里用 xhtml:link 声明 -->
<url>
  <loc>https://www.xxxxxx.cn/learning/</loc>
  <xhtml:link rel="alternate" hreflang="en" href="https://www.xxxxxx.cn/en/learning/"/>
</url>

选择建议:页数少用 B,页数多用 A;两者择一,不要混用造成不一致。


五、验证方法

hreflang 的验证核心是双向自洽检查——这可以脚本化:

# 抓取两个语言版本,确认各自都声明了对方与自身
check() {
  u=$1
  echo "== $u =="
  curl -s "$u" | grep -oE '<link[^>]*hreflang="[^"]+"[^>]*>'
}
check https://www.xxxxxx.cn/learning/
check https://www.xxxxxx.cn/en/learning/

逐条核对清单:

检查 通过标准
组内每一页都列出全部版本 是
每页列表包含自身 是
任意两页互为声明 成立
href 是 200 的终址 是
hreflang 与 canonical 不冲突 各指自己
存在 x-default 是(建议)
# 遍历多语言 URL 做一致性抽样(示例)
for p in /learning/ /en/learning/ /ja/learning/; do
  printf "%-20s hreflang_count=%s\n" "$p" \
    "$(curl -s https://www.xxxxxx.cn$p | grep -c 'hreflang=')"
done

六、多区域架构的选型

hreflang 之外,还要先决定"不同语言/地区放在哪",这决定了权重能不能集中:

架构 例子 权重集中度 运维成本 适用
ccTLD(国别域) xxxxxx.cn / xxxxxx.de 分散(各自独立) 最高 强地域合规要求
子域名 en.xxxxxx.cn 中等 中 多团队独立运维
子目录(推荐) xxxxxx.cn/en/ 最高 最低 多数中小站
参数 xxxxxx.cn/?lang=en 低,易重复 低 不推荐

选型判据:

  1. 优先子目录——权重集中在同一域名,运维最简单,hreflang 也最易对齐。
  2. 子域名与 ccTLD 会分散权重,只有在合规或组织要求下才用。
  3. 不要用参数表达语言——容易产生重复内容与 canonical 争议。

无论选哪种,每个语言版本都要有唯一、稳定的 URL,且能与 canonical、sitemap、hreflang 三者对齐。


七、故障速查

现象 原因 处理
版本不互跳 单向声明 补双向
某语言不收录 canonical 指到别语言 改自引用
搜索结果显示错误语言 x-default 缺失/错配 补 x-default
改版后 hreflang 失效 href 指向旧 URL 更新为终址
sitemap 与 head 冲突 两处都写了且不一致 择一
机器翻译页拉低质量 薄内容多语言 noindex 或改进质量

八、本章验收

# 本章核心验收:抽取所有 hreflang 声明
curl -s https://www.xxxxxx.cn/learning/ | grep -oE 'hreflang="[^"]+"'

多区域就绪后,最大的一次高风险操作是站点迁移——那需要可回滚的映射工程。

进入 keel 阅读