Catch the hreflang bug that silently kills international rankings: the missing return tag.
Most broken hreflang isn't a typo — it's non-reciprocity. Page A says "my French version is B," but B never points back to A, so Google ignores the entire cluster and your localized pages compete with each other instead of ranking in their markets.
hreflang-check starts from any one URL, follows every hreflang alternate, fetches each page, and verifies the annotations agree in both directions — and by language, not just by URL.
No API keys. No dependencies — just Python.
git clone https://github.com/seoprocheck/hreflang-check.git
cd hreflang-check
python3 hreflang_check.py https://example.com/Requires Python 3.8+. Standard library only — nothing to
pip install.
| Check | Why it matters |
|---|---|
| Reciprocity / return tags | If A → B, then B must → A with A's own language tag. The #1 cause of ignored clusters. |
| Self-reference | Every page must list itself — Google requires it, and most CMS templates forget. |
| x-default | The recommended fallback for unmatched users; flagged if the cluster has none. |
| Code validity | hreflang values must be well-formed (en, fr-FR, pt-BR, x-default) — catches classics like en-UK (should be en-GB). |
| Absolute URLs | Google requires absolute hrefs; relative ones are silently dropped. |
The reciprocity check is language-aware: it confirms each page references every other with that page's actual self-declared language, so a stray x-default pointing at the right URL can't mask a genuinely missing hreflang="en" return tag.
hreflang reciprocity audit https://example.com/en/
================================================================
cluster: 3 URL(s), 3 reachable
· https://example.com/en/
· https://example.com/fr/
· https://example.com/de/
----------------------------------------------------------------
https://example.com/fr/
✗ missing return tag to https://example.com/en/ (expected hreflang="en")
----------------------------------------------------------------
FAIL · 1 error(s), 0 warning(s)
python3 hreflang_check.py https://example.com/fr/ # start from any locale
python3 hreflang_check.py https://example.com/ --json # machine-readable
python3 hreflang_check.py https://example.com/ --max 40 # cap large locale setsExit code is non-zero when errors are found — drop it into CI to fail a build on broken hreflang. The --json output carries the full cluster, per-page findings, and counts.
MIT © SEO Pro Check · built by @seoprocheck.