搜索全站
Google SEO 11 分钟阅读

hreflang 技术实现与常见错误:返回标签、自引用与语言代码规范

hreflang 是最容易写错的多语言标签。本文讲清三种实现方式(HTML、HTTP 头、站点地图)、自引用规则、ISO 639-1 与 ISO 3166-1 代码规范,并给出 WordPress 自动输出代码与错误排查清单。

U
UFO_PF 2021-06-18 · 阅读 11 分钟
hr GOOGLE SEO
阅读提示
本文约 4,159 字,预计阅读 11 分钟。文中命令与配置均经过实测,可直接参考执行。

引言:标签写了,却完全没生效

多语言站点最常见的 hreflang 事故是:标签写得满满当当,Google 的「国际定位」报告却一条都没识别。原因通常是三类硬伤——没有自引用、语言代码写成 en-UK(英国的正确代码是 en-GB)、或者各语言版本之间没有互相指向(单向而非双向)。hreflang 的规则非常机械,任何一条不满足,整组标签都会被忽略。

原理分析:hreflang 的三条硬规则

hreflang 的作用是告诉搜索引擎「这个页面的其他语言/地区版本在这里」,用于把正确版本展示给对应地区的用户。Google 明确要求三件事:

规则 说明 常见违反
自引用 每个页面必须在 hreflang 组中包含自己 只列出其他语言
双向确认 A 指向 B,B 也必须指回 A 单向指向
代码合规 语言用 ISO 639-1,地区用 ISO 3166-1 Alpha-2 en-UK、zh-CN 大小写混用

语言代码必须单独可用,地区代码是可选的补充。只写地区不写语言是无效的(如 rel="alternate" hreflang="US" 不合规)。x-default 用于指定「未匹配任何其他语言时的兜底页」,不是必需的,但对语言选择页很有用。

三种实现方式各有适用场景:

方式 适用 限制
HTML <link> 绝大多数站点 需在 <head> 内
HTTP Link 头 PDF、非 HTML 资源 配置复杂
XML 站点地图 页面数量大、组关系复杂 维护成本高

三者不要混用,混用容易出现互相矛盾的声明。

保姆级实操

步骤一:确定 URL 与代码方案
先定语言与地区映射,例如 zh-Hans(简体)、zh-Hant(繁体)、en-US、ja-JP。注意中文可用 zh-Hans/zh-Hant 脚本子标签,也可用 zh-CN/zh-TW,但同一站点内必须统一风格。

步骤二:在 WordPress 里自动输出完整组
下面这段以自定义字段 mmf_translations(JSON,键为 hreflang 值、值为 URL)为数据源,自动补上自引用:

add_action( 'wp_head', 'mmf_output_hreflang', 2 );
function mmf_output_hreflang() {
    if ( ! is_singular( array( 'post', 'page' ) ) ) {
        return;
    }
    $id   = get_queried_object_id();
    $json = get_post_meta( $id, 'mmf_translations', true );
    $map  = json_decode( $json, true );
    if ( ! is_array( $map ) ) {
        $map = array();
    }
    // 自引用:必须包含当前页面自身
    $self = get_post_meta( $id, 'mmf_lang_code', true ) ?: 'zh-Hans';
    $map[ $self ] = get_permalink( $id );

    foreach ( $map as $code => $url ) {
        printf(
            '<link rel="alternate" hreflang="%s" href="%s" />' . "\n",
            esc_attr( $code ),
            esc_url( $url )
        );
    }
    if ( ! empty( $map['x-default'] ) ) {
        printf( '<link rel="alternate" hreflang="x-default" href="%s" />' . "\n", esc_url( $map['x-default'] ) );
    }
}

步骤三:输出到站点地图
如果语言版本很多,改用 XML 站点地图声明更清晰:

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
        xmlns:xhtml="http://www.w3.org/1999/xhtml">
  <url>
    <loc>https://mimangfei.com/hreflang-guide/</loc>
    <xhtml:link rel="alternate" hreflang="zh-Hans" href="https://mimangfei.com/hreflang-guide/"/>
    <xhtml:link rel="alternate" hreflang="en-US"   href="https://mimangfei.com/en/hreflang-guide/"/>
    <xhtml:link rel="alternate" hreflang="ja-JP"   href="https://mimangfei.com/ja/hreflang-guide/"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://mimangfei.com/en/"/>
  </url>
</urlset>

步骤四:非 HTML 资源用 HTTP 头声明
PDF 之类无法写 HTML 标签的资源,用响应头:

location ~* \.pdf$ {
    add_header Link '<https://mimangfei.com/en/report.pdf>; rel="alternate"; hreflang="en-US", <https://mimangfei.com/report.pdf>; rel="alternate"; hreflang="zh-Hans"' always;
}

步骤五:用命令验证输出
检查页面里是否包含自身、代码是否合规:

curl -s https://mimangfei.com/hreflang-guide/ \
  | grep -o '<link rel="alternate" hreflang="[^"]*" href="[^"]*" />'

# 检查是否存在非法的地区-only 代码或错误地区码
curl -s https://mimangfei.com/hreflang-guide/ \
  | grep -oE 'hreflang="[a-z]{2}-[A-Za-z]{2}"' | sort -u

步骤六:在 Search Console 里复核
旧版 Search Console 曾有「国际定位」报告,新版主要依靠「网址检查 → 国际化和本地化」部分查看 hreflang 是否被识别。识别不到时按步骤五的规则逐项排查。

步骤七:同步 canonical
canonical 必须指向自身语言版本的 URL,不能所有语言版本都 canonical 到主语言,那会直接抵消 hreflang 的作用。

常见踩坑

  1. 忘记自引用,整组标签被判不完整。
  2. 只做单向指向,A 指向 B 但 B 没指回 A。
  3. 把英国写成 en-UK,正确代码是 en-GB。
  4. 只写地区(hreflang="US")不写语言,格式不合规。
  5. 所有语言版本的 canonical 都指向主语言页,hreflang 被抵消。
  6. 案例:某外贸站用插件生成 hreflang,插件在翻译缺失的页面仍输出了指向空 URL 的标签,导致整站被判定标签无效。清理缺失项后,日文版页面的展示量在四周内上涨约两倍。
  7. HTML 与站点地图同时声明且内容不一致,形成矛盾信号。

总结

判断 hreflang 是否写对的三条标准:每个页面都包含指向自己的标签、所有版本之间双向互指、语言与地区代码符合 ISO 规范。落地时要统一代码风格(zh-Hans 与 zh-CN 不要混用),canonical 必须与 hreflang 一致指向自身版本,三种声明方式不要混用。验证用 curl 直接看输出,比在后台猜要快得多。若还在选型阶段,URL 结构决策(ccTLD、子域、子目录)请参考 国际站点URL结构;标签生效后,可用 服务器日志分析 观察各语言版本的 Googlebot 抓取分布;如果跨版本出现索引异常,还可结合 抓取预算优化 排查优先级问题。

U
UFO_PF作者

专注 WordPress 生态的实战作者,内容以「可复制、可验证」为第一原则。

留下你的想法

邮箱地址不会被公开。带 * 的为必填项。