hreflang tells search engines that several URLs are translations or regional variants of the same content, and which audience each is for. The concept is simple. The implementation fails constantly, because it demands a property that most content management systems make hard: every URL in a set must reference every other URL, including itself, and all of them must agree.
The reciprocity requirement
If the English page declares a German alternate, the German page must declare the English one back. Non-reciprocal annotations are ignored — silently. This is by design: without reciprocity, any site could claim to be the alternate of any other.
For a two-language site, that is four declarations. For eight locales, it is 64. The count is quadratic, which is why manual maintenance stops working almost immediately and why the tag is usually generated or not maintained at all.
The three implementation methods
HTML <link> tags in <head>. Most common, easiest to inspect, adds weight to every page proportional to the number of locales.
<link rel="alternate" hreflang="en-us" href="https://example.com/us/page" />
<link rel="alternate" hreflang="en-gb" href="https://example.com/uk/page" />
<link rel="alternate" hreflang="de-de" href="https://example.com/de/seite" />
<link rel="alternate" hreflang="x-default" href="https://example.com/page" />
HTTP Link headers. Required for non-HTML resources such as PDFs. Awkward to debug.
XML sitemap annotations. Best option at scale. Each <url> entry carries xhtml:link alternates for the whole set. Keeps the markup out of the pages, and it is generated from the same data that produces the sitemap — which is exactly where the locale mapping already lives.
For anything beyond a handful of locales, the sitemap method is the one that stays correct.
The failure taxonomy
Missing self-reference. Every page must include an hreflang entry pointing at itself. Omitting it is one of the most common errors and invalidates the set.
Wrong code format. The value is a language code, optionally followed by a region code — en, en-gb, de-at. Two errors recur: using a country code alone (uk is not a language), and using the wrong country code (en-uk is invalid; the ISO code for the United Kingdom is gb).
Conflict with canonical. If a page canonicals to a different URL, its hreflang annotations are effectively discarded — you have told Google this page is not the one to index. Each locale page should self-canonicalize.
Pointing at redirects or 404s. Alternates must be live, indexable URLs returning 200. A locale that was retired but left in the annotation set breaks the set.
Mixing absolute and relative URLs. Use absolute URLs with protocol and host, always.
Missing x-default. Not required, but it specifies where users outside your declared locales should land. Without it, the fallback is Google's judgment.
Annotations added by JavaScript. Unreliable. Server-render them.
What hreflang does and does not do
It does not consolidate ranking signals across locales — it is not a canonical. Each page ranks on its own merits.
It does not prevent duplicate content problems between locales in the way people expect. Two English pages for the US and UK with identical content are still near-duplicates; hreflang helps Google serve the right one to the right user rather than making them distinct.
What it does is influence which variant is served to a given user. Getting it right typically improves engagement metrics in each market — users landing on prices in their own currency and terminology — more than it changes rankings.
Debugging
Search Console's International Targeting report was retired, which removed the most convenient diagnostic. What remains:
- Crawl your own site and extract all
hreflangannotations, then verify reciprocity programmatically. A short script comparing each declared pair against the reverse declaration catches the majority of errors. - Check status codes for every URL in the annotation set. Redirects and 404s inside the set are common after a site restructure.
- Verify canonical agreement — each page's canonical should be itself.
- Sample-check what is actually served by querying from different regions, via a VPN or a rank tracker with location settings.
When not to bother
hreflang is worth the maintenance burden when you have genuinely distinct content per market — different currency, different regulations, different product availability, different terminology.
It is not worth it when the pages are identical except for a currency symbol, or when the "locales" are the same language with no meaningful difference. In those cases you are maintaining a complex, fragile annotation set to help Google choose between pages that are functionally interchangeable, and consolidating into one page usually performs better.
The question to ask before implementing is whether a user landing on the wrong variant would notice. If the answer is no, you probably do not need the tag.