关于 seo-international
一项有条件运行的 SEO 技能,用于审查多语言网站的 hreflang 和链接级本地化。它检查语言标签、双向备用链接、自引用和 canonical 冲突,不会臆测缺失的语言区域信息。
主要功能
- 01验证 BCP-47 语言标签
- 02检查双向及自引用备用链接
- 03检测 hreflang 与 canonical 冲突
- 04检查 x-default 和文档语言
- 05生成并验证 hreflang 修复
适用场景
- 01审查各语言版本间的 hreflang
- 02查找无效语言标签或缺少回链
- 03检查本地化 URL 与 canonical 标签
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ hainrixz/ claude-seo-ai --skill seo-international安装后在 Claude Code 中输入/seo-international确认已加载。
详细介绍
seo-international(M20)
hreflang 会告知搜索引擎应提供哪个语言或地区的 URL。本模块是条件触发的:仅当 seo-vertical-detect 标记网站为多语言网站时才运行(存在多个 lang/语言区域 URL、语言切换器或现有 hreflang)。对于单语言网站,所有发现的状态均为 not_applicable,严重性为 0。Schema 类型问题交由 references/schema-tier1.md 处理;本模块仅负责链接级本地化。
输入
根据调度信封中指定的 PageSnapshot 进行处理:从 <run_dir>/pages/<slug>.json 中读取 parsed(其中包含 hreflang[]、canonicals[]、parsed 中的 <html lang>),以及 headers.link 和 <run_dir>/pages/ 下的同级页面,以检查互惠性;对 pages/<slug>.html 使用 Grep 查找原文证据;站点产物位于 <run_dir>/site/{robots.json,sitemaps.json,discovery.json}。audit.mjs 已输出的确定性发现列在 <run_dir>/findings.deterministic.json 中——不要重新输出这些 id;仅添加经模型判断的发现。如果直接传入 URL/路径调用且不存在快照,先运行 node "${CLAUDE_PLUGIN_ROOT}/scripts/snapshot.mjs" <target> --out "${CLAUDE_PLUGIN_DATA}/runs",并使用输出的快照路径。
审计
基于 PageSnapshot 处理(当 render.used 不为 none 时使用 parsed_rendered,否则使用 parsed)。从 <head> 中的 <link rel="alternate" hreflang="..."> 读取 hreflang(如果存在,也接受 HTTP Link: 标头 / sitemap xhtml:link):
- 互惠性 — 如果页面 A 声明了备用页面 B,B 必须反向声明 A。Google 会忽略单向 hreflang。
- BCP-47 有效性 — 每个
hreflang值都必须是有效的语言标记(en)或语言-地区标记(en-GB、pt-BR);地区代码必须是 ISO-3166-1 alpha-2,不能根据语言猜测国家(en-UK无效;应使用en-GB)。 - 自引用 — 页面在自己的 hreflang 集合中列出自身。
- x-default — 语言选择器 / 后备 URL 至少要有一个
hreflang="x-default"。 - hreflang↔canonical 冲突 — hreflang URL 必须是自指 canonical;如果 hreflang 指向的 URL 的
rel=canonical是另一个页面,则会使整个集群失效(与 M2/seo-indexability 交叉检查)。 <html lang>一致性 — 文档的lang属性必须与此 URL 在其自身 hreflang 条目中指定的语言区域一致。
修复
- 自动(
fixable: auto):当语言区域→URL 映射已知时(由用户提供、来自 sitemap 或从备用链接中发现),生成完整且互惠的 hreflang 链接集合——包含每个语言区域和单个x-default——作为供fix使用的<head>差异。采用增量方式且结果确定。 - 建议(
fixable: proposed):根据发现的备用链接推断出的部分集合,需要用户在写入前确认语言区域映射。 - 提示(
fixable: advisory):“此网站似乎是多语言网站,但没有语言区域映射”——工具绝不写入此项。 - 绝不伪造语言区域、地区代码或备用 URL。如果映射不完整,留下明确标记的
TODO(locale)占位符并询问用户。
验证
- 离线:
node "${CLAUDE_PLUGIN_ROOT}/scripts/hreflang-check.mjs" --snapshot <pages/<slug>.json>(或使用--url <u>/--file <path>)——解析<link>标签和 HTTPLink标头(entries、header_entries)中的备用集合,验证 BCP-47 标记(invalid_bcp47),并报告has_x_default、self_referenced、duplicate_langs以及 canonical 与 hreflang 的冲突。在此模式下不检查互惠性:该检查需要使用--url <u> --deep [--budget 25] [--ua <preset>],以获取每个声明的备用页面。 - 检查互惠性需要获取每个声明的备用页面;当这些 URL(或 sitemap 层级)不可用时,状态为
needs_api,绝不误报为pass。
检查结果
检查结果符合 schema/finding.schema.json;轴为 search。对于单语网站,每个 id 的严重程度均为 0,状态均为 not_applicable。严重程度策略:5 仅用于网站/模板层级上会造成灾难性后果、令资格失效的事实;4 为重大 · 3 为中等 · 2 为轻微 · 1 为表面问题 · 0 为信息性问题——且只有活动类别中严重程度为 5、状态为 established 的 fail 才能限制评分(references/scoring-model.md)。
M20.hreflang.missing_reciprocal— 页面为某个 URL 声明了hreflang="de-DE",但该 URL 没有反向指向此页面;Google 会忽略单向注释,因此无法形成集群(fail,严重程度 4,fixable: proposed,置信度established)。evidence.observed引用了单向的<link>。M20.hreflang.invalid_bcp47— 例如hreflang="en-UK"(fail,严重程度 3,fixable: auto,置信度established;建议使用en-GB)。一个错误值会使对应条目失效,而非整个集合。M20.hreflang.missing_self— 页面未包含在自身的备用语言集合中(fail,严重程度 3,fixable: auto,置信度established)。M20.hreflang.canonical_conflict— 某个 hreflang URL 的rel=canonical指向了不同的页面,这会使集群失效(fail,严重程度 4,fixable: proposed,置信度established;交叉检查 M2)。M20.hreflang.missing_xdefault— 集群没有x-default回退项(warn,严重程度 2,fixable: auto,置信度directional——x-default是建议项,并非必需项;缺少它会降低选择器路由效果,而非破坏集群)。M20.lang.mismatch—<html lang>与此 URL 在自身 hreflang 条目中声明的地区设置不一致(warn,严重程度 2,fixable: auto,置信度directional)。M20.hreflang.not_applicable— 单语网站(not_applicable,严重程度 0)。 平台条件 id。 此模块还会发出 1 个仅在profile.json指定平台(shopify)时触发的 id。该 id 编入references/routing.md§ 平台条件检查结果 id,并在references/platforms/<id>.md§10 中详细说明。
每条检查结果:verification.reproduce 会运行上述 hreflang 检查命令;expected_impact 按区间划分并标注置信度(不使用无依据的百分比)。
诚信原则
- hreflang 是定位/聚类信号,而非排名加成:它会选择在某个地区显示哪个现有 URL,但不会提升排名。不要把它宣传成排名手段。
- hreflang 不能解决内容单薄或机器翻译问题,也不能替代
rel=canonical——两者应配合使用。 - Bing 和 Yandex 对它的使用很有限,甚至完全不用;有文档记录的受益方是 Google。不要声称它在各搜索引擎上的效果一致。
- 不能仅凭一个页面断言存在互惠关系。如果未在抓取预算内获取备用页面,该检查结果应为
needs_api——单方面的视角不能证明链接是单向的。