AI Hreflang Audit: Catch Bilingual SEO Bugs in 30 Minutes

Use an LLM to audit hreflang on a multi-locale site: missing return tags, wrong codes, slug mismatches. Real prompt, real tools, June 2026.

Bilingual sites quietly leak ranking signals when hreflang is wrong: a typo in translationKey, a one-way link, a missing self-reference, or the classic zh vs zh-CN mismatch. Google’s own rule is blunt — if two pages don’t both point to each other, the annotation is ignored entirely (Google Search Central). This tutorial uses an LLM to pattern-match thousands of rows you’d otherwise eyeball, then verifies the result with a free dedicated hreflang tester. The output is a CSV of bad pairs you fix in source, validated against rendered HTML.

TL;DR

  • Export one CSV row per page (slug, lang, translationKey, canonical_url, rendered <link rel="alternate"> block), feed it to a long-context model with a fixed checklist, fix in source, re-render, and re-validate.
  • The LLM catches the five structural bugs: missing pair, key mismatch, wrong locale code, missing self-reference, missing x-default. It does not check that hreflang URLs return 200 — a crawler does that.
  • Google’s International Targeting report is gone (deprecated 2022, removed since). As of June 2026 you monitor with Screaming Frog, TechnicalSEO.com’s free tester (it accepts a whole sitemap), or hreflang.org — not Search Console.
  • Best fit: 50+ article pairs. Under 50, a single Screaming Frog crawl is faster than building the pipeline.

What this audits, and what it doesn’t

This pipeline checks hreflang as it appears in the <head> of HTML pages and in your XML sitemap (<xhtml:link> elements). It does not cover HTTP-header hreflang, which content sites rarely use. The LLM does the cross-referencing across thousands of rows; it cannot fetch URLs, so a separate crawler confirms each hreflang target actually returns 200.

It fits owners of bilingual or multi-locale content sites — EN/ZH, EN/JA, EN+ES+FR — on Astro, Next.js, Hugo, or any static-ish stack. If you have a translationKey or i18n-key field linking translations, the workflow uses it directly. If you don’t, step 1 still works: the slug pair (en/foozh/foo) is the key.

Run it after every content batch (10+ new articles or translations), before any SEO push (link campaign or sitemap resubmit), and immediately after renaming a locale code or slug. Those renames are exactly when reciprocity quietly breaks.

The five bugs and what catches each

Google treats hreflang as a hint, not a directive — canonical tags, content similarity, and which page is indexed can all override it. But a broken annotation cluster is simply ignored, so these five defects waste the signal entirely. As of June 2026, here is what each maps to in a real crawler:

BugWhy it breaksScreaming Frog report
Missing pairArticle exists in one lang only; cluster is incompleteHreflang › Missing Return Links
Key/slug mismatchSame translationKey resolves to non-matching slugsshows as broken return link
Wrong locale codezh instead of zh-CN/zh-Hant; underscore (en_US) instead of hyphenHreflang › Incorrect Language & Region Codes
Missing self-referencePage omits an alternate for its own languageInconsistent Language & Region Confirmation Links
Missing x-defaultNo fallback for unmatched localesHreflang › Missing X-Default

Two format rules cause most “wrong code” cases. Language uses ISO 639-1 (en, zh); an optional region uses ISO 3166-1 Alpha-2 after a hyphen (en-GB, zh-CN) — never an underscore, and never a region code alone (hreflang="US" is invalid because Google won’t infer the language). The whole value follows BCP 47.

Before you start

  • Write down your strategy. Most bilingual sites emit <link rel="alternate" hreflang="en" href="..."/> for each locale plus one x-default. Note your exact tag so you can verify against rendered output.
  • Lock one Chinese code. Pick zh, zh-CN, zh-Hans, or zh-Hant and use it sitewide. Mixed codes are the top cause of clusters being ignored.
  • Use a long-context model. A 1000-row CSV with the rendered tag column easily exceeds 100k tokens. Claude Sonnet 4.6 and Gemini 3.1 Pro both carry 1M-token context as of June 2026 (Sonnet 4.6 is the cheaper workhorse at $3/$15 per 1M tokens in/out).

Step by step

  1. Export the CSV. One row per article. Columns: slug, lang, translationKey, canonical_url, and the full rendered <link rel="alternate"> block for that page. A short Node script reading your content collection emits this in under a minute.

  2. Prompt the model with a fixed checklist. Keep it deterministic — same prompt every run so you can diff results month to month:

Audit this hreflang setup. For each row, flag:
1. Missing pair: article exists in one lang but not the other (group by translationKey)
2. Key/slug mismatch: same slug but different keys, or same key but slugs do not align
3. Wrong locale code: anything outside [en, zh-CN]; flag underscores and region-only codes
4. Missing self-reference: row omits an hreflang for its own lang
5. Missing x-default
Return a TSV with columns: issue, slug, lang, suggested_fix
  1. Fix in source. Only two real fixes exist: ship the missing translation, or correct the translationKey. Never “fix” it by deleting an hreflang link — that hides the issue from the audit but not from Google.

  2. Re-render and validate. Re-crawl with Screaming Frog (free up to 500 URLs; the hreflang reports above export the exact bad rows) or paste your sitemap URL into TechnicalSEO.com’s hreflang tester, which checks every alternate at once. Spot-check five representative pages in HTML view: a popular EN article, its ZH pair, an EN-only article (still needs x-default and a self-reference), the homepage, and one tag/index page.

  3. Resubmit the sitemap. Update and resubmit to Search Console; ping all child sitemaps if you use an index. Note the limits: a single sitemap caps at 50,000 URLs / 50MB uncompressed. There is no Search Console hreflang report to watch anymore — re-run the crawler instead, and confirm error counts trend to zero.

Calibrate the prompt before you scale

Don’t trust a fresh prompt on the whole site. Run it on one subdirectory or tag (30–50 articles) where the model is most accurate, then plant a known bug — delete one return link, swap a code to zh — and confirm the LLM catches it. If it misses a planted bug, the CSV or checklist is too thin. Save each run’s TSV next to the fix commit; diffing two months of TSVs shows which bug class is creeping back. Only scale to the full site after the prompt hits 100% on your planted bugs.

Quality check

  • After re-rendering, open three pages and inspect the <head>: each needs a self-referencing hreflang, every sibling-locale alternate, and one x-default.
  • Confirm hreflang URLs return 200, not 301 or 404 — the model can’t test this, so a crawler or broken-link script must. See finding broken links with AI.
  • Spot-check each page’s canonical. Hreflang pointing to a non-canonical URL silently fails the whole cluster.

Bake it into the pipeline

  • Save the audit prompt in your repo and run it in CI on any PR touching more than 10 articles.
  • Keep the allowed locale codes as data, not inside the prompt — easier to update when you add a third language.
  • Turn repeated failures into a build assertion: if the same translationKey breaks twice, assert in your build that each key appears in exactly N locales. That moves the bug from “audit catches it” to “build refuses to ship it.”

Common mistakes

  • Using zh where you meant zh-CN/zh-Hant, or en_US instead of en-US. Google treats these as different (or invalid) signals.
  • Forgetting x-default. Without it, users in unmatched locales get a worst-case fallback.
  • Hreflang in <head> pointing to a non-canonical URL — cluster silently ignored.
  • Asymmetric pairs: EN links to ZH but ZH doesn’t link back. Clusters must be reciprocal or Google drops them.
  • Auditing the live HTML but not the sitemap. Both must agree; conflicting signals get both ignored.
  • Applying an AI “fix” without checking HTML. Models occasionally suggest correct-looking but wrong locale codes.

FAQ

  • Does Google penalize wrong hreflang? No direct penalty, but it misroutes traffic to the wrong locale, dropping CTR and conversions in that market. Google also confirmed (May 2025) that hreflang is a hint — canonical, content similarity, and indexing can override it.
  • Where do I monitor hreflang now that Search Console’s report is gone? The International Targeting report was deprecated in 2022 and removed. As of June 2026, use Screaming Frog’s Hreflang reports, TechnicalSEO.com’s free tester (it accepts a sitemap), or hreflang.org.
  • Do I need hreflang on every page or just articles? Every indexable page with a translation: homepage, category pages, and articles all count.
  • What about EN-only pages? Self-reference the EN page and emit x-default pointing to it. Don’t invent a ZH alternate that doesn’t exist.
  • How often does the model hallucinate an issue? Around 5% of flags are false positives on a clean prompt. Always verify before applying a fix.
  • Can I do this without translationKey? Yes — group rows by your slug-pair convention (en/foozh/foo) and tell the model the rule.

Tags: #Tutorial #SEO #AI coding #hreflang #Bilingual