Hreflang Validator
Validate hreflang markup quality and reciprocal language links.
Hreflang Validator — Alternate & Reciprocal Check
Validate multilingual hreflang markup: code format, x-default coverage, duplicates, and reciprocal alternate links.
How to Use
- Enter a URL that should be part of your hreflang cluster
- Run validation and review code, x-default, and self-reference issues
- Enable reciprocal checks if needed and fix disconnected locales
FAQ
Hreflang check: what the validator tests and how to read it
This hreflang checker fetches your page, collects every <link rel="alternate" hreflang="…" href="…"> tag in the HTML and audits the cluster of language versions. At the top you get three counts: alternate links found, unique codes, and issues. Below that come the issues and a table with code, target URL, HTTP status and a Reciprocal column.
What counts as an issue:
- No hreflang links at all — the markup isn't in the HTML, or a script injects it after load (the tool doesn't execute JavaScript).
- Invalid code — not shaped like "language" or "language-region" (
en,en-gb,pt-br) and notx-default. - Duplicate code — the same code points to different URLs.
- Missing x-default — a recommendation, not an error.
- Missing self-reference — no alternate points to the page you tested. Host case and a trailing slash are ignored, but
httpvshttpsandwwwvs non-www are not.
With the reciprocal switch off, the tool requests headers for every alternate URL and shows the final status code. Switch it on for proper hreflang testing of return links: the first eight versions are downloaded in full and scanned for a link back to your page. Versions beyond eight show "—".
Hreflang syntax
<link rel="alternate" hreflang="en-us" href="https://example.com/us/pricing/" /> <link rel="alternate" hreflang="en-gb" href="https://example.com/uk/pricing/" /> <link rel="alternate" hreflang="de" href="https://example.com/de/pricing/" /> <link rel="alternate" hreflang="x-default" href="https://example.com/pricing/" />
- Language — a two-letter ISO 639-1 code:
en,de,fr,pl. - Region (optional) — ISO 3166-1 alpha-2 after a hyphen:
en-gb,de-at. A region alone is invalid:hreflang="gb"orhreflang="us"does nothing. - Case doesn't matter:
en-GBequalsen-gb. - URLs must be absolute, including the protocol. The tool resolves relative URLs so it can test them, but write full URLs in your markup.
Code traps a format check won't catch
The validator checks the shape of a code, not whether it exists, so scan the table yourself:
en-ukis wrong. The United Kingdom isgb;ukis the Ukrainian language. Useen-gb, even if your folder is called/uk/.en-euoren-latamaren't valid regions. Target countries one by one, or use language only.zh-Hant,zh-Hans(script subtags) andes-419(Latin America) are accepted by Google but flagged by the strict format check. If you use them, that warning is a false positive.
x-default: when and where
x-default is the page for everyone who matches no listed code — usually a language selector or your main international version. It's optional, but on sites that geo-redirect from the root it's the clearest way to tell Google that the bare homepage isn't another language version. Don't auto-redirect x-default by IP: Googlebot crawls mostly from US addresses and may never see your other versions.
Language only or language-region?
Use a region code only when versions genuinely differ: prices and currency, shipping, legal terms, local spelling. If you have one English version for everyone, en is enough. Near-identical en-us and en-gb pages with hreflang are fine — Google doesn't treat them as duplicates and shows each country its own.
Return links and self-reference
Hreflang only works in pairs. If the US page points to the UK page but the UK page doesn't point back, Google ignores the relationship. Every version must list all versions in the cluster, itself included. That is why hreflang should be generated from one source of truth (a shared translation map) rather than typed per page. WPML and Polylang do this in WordPress; Shopify Markets does it on Shopify.
Common hreflang errors
| Error | Effect | How to find it |
|---|---|---|
| Alternate URL redirects | Google expects the final URL; chains weaken the signal | The status column shows the post-redirect code, so run the URLs through the redirect checker |
| Alternate is 404 or noindex | That version drops out of the cluster | Status column; noindex via the meta tag analyzer |
| Canonical points to another language | Google folds the versions together and shows one | Each version should be self-canonical |
| No return link | Relationship ignored | Reciprocal mode |
| Different URL forms (slash, www, parameters) | Self-reference and return links don't match | Compare the URL column with canonicals |
| Hreflang on untranslated pages | Users land on the wrong language | Only add hreflang once a translation exists |
Hreflang testing, step by step
- Check the homepage and one page per template (category, product, article) with reciprocal off: confirm the markup is output at all, codes are valid, and x-default and self-reference are present.
- Turn reciprocal on for the same pages. Every "No" is a version that doesn't link back — typically a translation published on one side but not yet linked from the other.
- Open each version listed and test it too. All versions should carry the identical set of links; five alternates on one and four on another means the cluster is out of sync.
- Compare each version's canonical with its hreflang URL. They must match character for character.
- After fixing, request indexing for key pages via URL Inspection. Google rebuilds clusters gradually as it recrawls every version.
Where it usually breaks
In WordPress, hreflang comes from the multilingual plugin (WPML, Polylang) while the SEO plugin outputs the canonical. Trouble starts when a page isn't linked to its translation in the plugin settings, so no hreflang appears for it. On custom CMSs the tags are usually built in the header template. The classic bug there is taking the current URL from the request, UTM tags and sort parameters included, so the self-reference never matches the canonical. Headless setups add one more trap: tags rendered only client-side are invisible to this validator and appear late for Google.
Three ways to implement hreflang, including the sitemap
You can declare hreflang in the <head>, in an HTTP Link header (the only option for PDFs) or in your XML sitemap. Pick one: mixing is allowed, but conflicting sources make debugging painful. This validator reads the HTML tags only.
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:xhtml="http://www.w3.org/1999/xhtml">
<url>
<loc>https://example.com/us/pricing/</loc>
<xhtml:link rel="alternate" hreflang="en-us" href="https://example.com/us/pricing/"/>
<xhtml:link rel="alternate" hreflang="en-gb" href="https://example.com/uk/pricing/"/>
<xhtml:link rel="alternate" hreflang="x-default" href="https://example.com/pricing/"/>
</url>
<!-- repeat a full <url> block for /uk/pricing/ -->
</urlset>
Sitemaps suit large sites because they keep page HTML lean, but every version needs its own <url> entry with the full set of links. Parse yours with the sitemap analyzer.
Google has retired the International Targeting report in Search Console, so hreflang errors now surface only through external checks and URL Inspection, which shows the canonical Google selected. Official rules are in Google's documentation.
Improve search rankings
SEO problems may be costing you traffic. Cascade link building will improve site visibility in search.