Search Console 里的 hreflang 报错:报告没了,现在怎么修

Google 在 2022 年下线了 International Targeting 报告,hreflang 错误不再显示在 Search Console 里。本文教你改用爬虫工具找出 No return tags、语言码无效、目标 404 等错误,并逐一修复。

如果你想在 Google Search Console 里打开 International Targeting 报告看 hreflang 错误,却怎么也找不到,那第一件要明白的事就是:Google 已于 2022 年 9 月 22 日弃用该报告,并把它从 Search Console 中移除了。 它已经不存在,而且 Search Console 的界面里现在任何地方都不再呈现 hreflang 错误(Enhancements 和 Page indexing 报告里也没有)。Google 仍然会读取并使用 hreflang 注解——只是不再就此出报告了。

最快的修法:Screaming Frog SEO Spider 爬一遍你的站(免费版可爬 500 个 URL),打开 Hreflang 标签页读各个 filter。它们标出的正是旧报告标过的那些问题——No return tags(缺回链)、语言码无效、目标非 200——而且精确到具体 URL,不再是一个汇总数字。然后把每一对被标出的页面修掉,重爬一遍。

通用 hreflang 概念概览,看 hreflang 警告快速指南

hreflang 错误现在去哪儿看(截至 2026 年 6 月)

以前你这么做现在改成这样
打开 Search Console → Legacy tools → International Targeting用 Screaming Frog、Sitebulb、Ahrefs Site Audit 或 Semrush 爬
看汇总的 “No return tags” 数量看爬虫逐 URL 的 Hreflang 标签页 / Site Audit 问题列表
在 Search Console 里设国家定向国家定向功能已取消;Google 改从 hreflang、ccTLD、服务器位置和内容推断地区
等报告刷新立刻重爬;想看 Google 本身的判断,就在 URL Inspection 里重新抓取页面

URL Inspection 工具仍可用来抽查单个页面:它会显示 Google 抓到的实时 HTML,你能确认 <link rel="alternate" hreflang> 标签是否真的出现在返回的 markup 里。但它不会跨页面列出 reciprocity(回链)错误——那个还得靠爬虫。

常见原因

按命中率从高到低。

1. “No return tags”——A 链 B 但 B 不回链

hreflang 必须双向。/en/article/ 声明 hreflang="zh-Hans" 指向 /zh/article/,那 /zh/article/ 必须声明 hreflang="en" 指回。引用 Google 官方文档的原话:“If two pages don’t both point to each other, the tags will be ignored.”(两个页面不互指,标签就会被忽略。)不对称的声明会被静默丢弃——不只是坏掉的那条,而是这一对的整组。

这是最常见的 hreflang 错误。在 Screaming Frog 里它出现在 Hreflang → Missing Confirmation Links(当语言码不完全一致时,则是 Inconsistent Language & Region Confirmation Links)。

怎么手动判断

# 对照一对页面的两边
curl -s https://site.com/en/article/ | grep -oE 'hreflang="[^"]+" href="[^"]+"'
curl -s https://site.com/zh/article/ | grep -oE 'hreflang="[^"]+" href="[^"]+"'

/en/ 有 4 行 hreflang、/zh/ 只有 1 行,缺的 3 个就会触发 “no return tags”。

2. 缺少自引用(self-referencing)hreflang

一个常被漏掉的硬性要求:每个页面都必须包含一条指向自己的 hreflang。 Google 文档原话:“Each language version must list itself as well as all other language versions.”(每个语言版本必须既列出自己,也列出所有其它语言版本。)如果 /en/article/ 列了 zh-Hansx-default 却漏了自己的 en 自引用,爬虫会报 Missing Self Reference,回链关系的计算也可能因此断掉。

怎么判断:在上面 curl 的输出里,确认每个页面都列出了自己的语言码、指向自己的 URL。Screaming Frog 里这是 Hreflang → Missing Self Reference 这个 filter。

3. “Invalid language code”——格式错

Google 只接受 ISO 639-1 的语言码和 ISO 3166-1 Alpha-2 的地区码,其它一律拒收。常见错误:

  • hreflang="en_US"——用了下划线,必须用横杠 en-US
  • hreflang="english"——写了全称,应该用 ISO 码 en
  • hreflang="en-UK"——UK 不是 ISO 3166-1 码,英国是 GB,应写 en-GB
  • hreflang="zh-CHS"——旧的微软 locale 码,应该用 ISO 的 zh-Hans

关于中文:纯 hreflang="zh"有效的(Google 接受 ISO 639-1 单语言码),但当你同时提供简繁两套时,用脚本子标签 zh-Hans(简体)和 zh-Hant(繁体)更清晰,下文也推荐 zh-Hans。早先那句「Google 要求用 zh-CN」其实并不准确——地区码是可选的,脚本子标签才是精确区分简繁的办法。

怎么判断

curl -s https://site.com/en/article/ | grep -oP 'hreflang="\K[^"]+' | sort -u

每个对照 BCP 47 / language-tags 参考(ISO 639-1 语言 + 可选 ISO 3166-1 Alpha-2 地区)。Screaming Frog 里这归在 Hreflang → Incorrect Language & Region Codes

4. “URL not found”——hreflang 目标返回 404 或跳转

你加了 hreflang 指向 /de/article/,但德语版还没建,或者 URL 改过了。目标返回 404——或者 301/302 跳到别处——都会让这条 hreflang 失效。Google 要求每条 hreflang 都落在一个存活的、最终的 200 URL 上。

怎么判断

for url in $(curl -s https://site.com/en/article/ | grep -oP 'hreflang="[^"]+" href="\K[^"]+'); do
  echo -n "$url: "
  curl -sI "$url" | head -1
done

任何非 200 响应 = hreflang 坏了。Screaming Frog 里这是 Hreflang → Non-200 Hreflang URLs filter;用 Reports → Hreflang → Non-200 Hreflang URLs 把出错的源页面导出。

5. hreflang 声明的 URL 不是 canonical

你 hreflang 指向 /zh/article?ref=newsletter,但那个页面的 canonical 是 /zh/article/。Google 当作 hreflang 指向了非 canonical URL,会降权处理。更糟的是:如果你的 <link rel="canonical"> 和 hreflang 自引用对不上,页面就发出了互相矛盾的信号。

怎么判断:每个 hreflang URL 都对照该页面的 rel="canonical",必须完全一致(同协议、同主机名、同尾斜杠、无跟踪参数)。canonical 这一侧详见 双语 canonical 错配

6. 缺 x-default

严格说不是错误,但接近警告。没有 x-default,对于 locale 不匹配任何已声明 hreflang 的用户,Google 没有声明的 fallback。而且如果同一组里有些页面带 x-default、有些不带,爬虫会报 reciprocal(回链)不一致。

怎么判断:看有没有 <link rel="alternate" hreflang="x-default" href="..." />。没有(或者只在部分页面上有),就一致地加上,指向你的主语言版本,或一个语言选择页。

7. hreflang 同时存在于两处

HTML <link> 标签里加了 hreflang,又在 HTTP Link 头(或 sitemap)里也加了。Google 三处都读,但 Google 文档明确警告多套实现「没有好处」(no benefit),且「更难维护」(much harder to manage)——重复或漂移的两份副本本身就成了不一致的来源。

怎么判断

curl -sI https://site.com/en/article/ | grep -i 'link:'

HTML <link rel="alternate"> 和 HTTP Link 头都在发 hreflang,就选一个(内容站通常用 HTML),删掉另一个。

最短修复路径

第 1 步:从单一源生成 hreflang

不要每页手写 hreflang——不对称就是这么混进来的。从一份 translation-key map 生成每页的整组,并且带上自引用

// site.config.mjs
export const locales = {
  en: { hreflang: 'en', urlPrefix: '/en/' },
  zh: { hreflang: 'zh-Hans', urlPrefix: '/zh/' },
};

export function hreflangAlternates(translationKey) {
  // 为每个 locale 都生成一条(包括当前页自己 = 自引用)
  const alternates = Object.values(locales).map(({ hreflang, urlPrefix }) => ({
    hreflang,
    href: `https://site.com${urlPrefix}${translationKey}/`,
  }));
  alternates.push({ hreflang: 'x-default', href: `https://site.com/en/${translationKey}/` });
  return alternates;
}

在 layout 里循环这个列表吐 <link rel="alternate"> 标签。因为每个页面都用同一份 map 渲染完整一组,每页都会自引用,每对天然就是对称的。

第 2 步:用有效、无歧义的 locale 码

ISO 639-1 语言 + 可选 ISO 3166-1 Alpha-2 地区。无空格、无下划线、不要瞎编地区码:

zh-CHS(旧微软码)zh-Hans(简体)或 zh-Hant(繁体)
pt(你同时供两套时有歧义)pt-BRpt-PT
en_USen-US
en-UKen-GB(UK 不是 ISO 码)
englishen

第 3 步:校验所有 hreflang URL 都返回 200

# CI 脚本——从 sitemap 抽所有 hreflang URL 逐一校验
xmllint --xpath '//*[local-name()="link"]/@href' sitemap.xml | grep -oP 'href="\K[^"]+' | while read url; do
  status=$(curl -s -o /dev/null -w "%{http_code}" "$url")
  [ "$status" = "200" ] || echo "BAD: $status $url"
done

第 4 步:加 x-default

每个同组页面上都要有:

<link rel="alternate" hreflang="x-default" href="https://site.com/en/article/" />

指向你的主 / fallback 语言版本(如果有真正的语言选择页,也可指向它)。

第 5 步:只用一种发布机制

只选一个,删掉其余:

  • HTML <link> 标签 放在 <head>——静态站和内容站最简单
  • HTTP Link——非 HTML 资源(PDF 等)最合适
  • Sitemap <xhtml:link>——超大站、不方便逐页改 <head> 时合适

Google 说多套实现对搜索没有任何好处,而三套实现要保持同步要难得多。选一个坚持。

第 6 步:重爬确认(别再等 Search Console)

既然 International Targeting 报告没了,你的反馈回路现在是爬虫,而不是 Google:

  1. Screaming Frog 里重爬,跑 Crawl AnalysisUnlinked Hreflang URLs filter 需要它才会填充数据),确认 Hreflang 标签页显示零问题。
  2. 在 Search Console 的 URL Inspection → View crawled page → HTML 里抽查一个页面,确认 Google 在实时 markup 里看到了你的 hreflang 标签。
  3. 在 Search Console → Sitemaps 重新提交 sitemap,让 Google 重新发现修正后的页面。重新索引和重新评估 hreflang 通常需要几天,大站可能要 2-3 周。

第 7 步:用专门工具验证

把 URL 扔进 TechnicalSEO hreflang 测试器Aleyda Solis 的 hreflang 生成/校验工具。它们能精确指出哪一对不对称,这是收尾「no return tags」最快的办法。

怎么确认修好了

  • 跑完 Crawl Analysis 后,Screaming Frog 的 Hreflang 标签页干净:没有 Missing Confirmation LinksMissing Self ReferenceIncorrect Language & Region CodesNon-200 Hreflang URLs
  • 手动 curl 任意一对配对页面,看到的是完全对称的 hreflang 组(两边语言码一致、每页都自引用、还带 x-default)。
  • TechnicalSEO 或 Aleyda Solis 校验器对抽样的那一对报零错误。
  • URL Inspection 里,实时页面被抓取的 HTML 含有你的 hreflang <link> 标签。

常见问答

International Targeting 报告现在在 Search Console 哪里? 没了。Google 已于 2022 年 9 月 22 日弃用它并从 Search Console 移除。hreflang 错误现在在 Search Console 界面任何地方都不再呈现,所以改用爬虫(Screaming Frog、Sitebulb、Ahrefs、Semrush)来找。

Google 还支持 hreflang 吗? 支持。Google 明确表示「继续支持 hreflang」,且其多语言/多地区的建议依然有效。被移除的只是报告和单独的国家定向设置——注解本身仍然有效,仍然影响某个用户会看到哪个语言版本排名。

hreflang="zh" 算错吗?需要写 zh-CN 吗?zh 是有效的;Google 接受单独的 ISO 639-1 码。地区码可选。如果你同时供简繁两套,用脚本子标签 zh-Hanszh-Hant 区分——这比用国家码 zh-CN 更清晰。

真的需要自引用的 hreflang 标签吗? 需要。Google 文档说每个语言版本必须既列出自己、也列出所有其它版本。从一份 map 生成整组(第 1 步)会自动带上自引用。

hreflang 没错,但排名出来的还是错误的语言版本,为什么? hreflang 是聚类和替换的提示,不是排名的强制覆盖。如果回链断了(任何不对称都会作废整组)、canonical 与 hreflang 自引用矛盾、或者改动后 Google 还在重爬,Google 仍可能选另一个 URL。先修回链和 canonical,再给它一两周。

修好后多久能见效? 现在已经没有报告可盯了,所以先用爬虫立刻确认 markup。要 Google 据此调整,预计几天到约 2-3 周,取决于抓取频率和站点规模。重新提交 sitemap 能加快重新发现。

预防建议

  • 从单一 translationKey 源生成 hreflang——永远不要每页手写——并在生成的整组里带上自引用。
  • CI 校验 hreflang:每个 URL 返回 200、每个码有效(ISO 639-1 + ISO 3166-1 Alpha-2)、每对对称、同组所有页面都有 x-default
  • 只选一种发布机制(HTML link 标签最常用),不混用。
  • 加新 locale 时,重爬已有页面,确认它们都吐了新 locale 的 hreflang。
  • 定期跑一次 Screaming Frog 或 Ahrefs Site Audit,因为 hreflang 漂移时 Search Console 不会再警告你。

相关阅读

标签: #排查 #SEO #排查 #hreflang