Hreflang is the mechanism that tells search engines about your multilingual or multi-regional pages. It says: here is the equivalent of this page for users in [language]-[region].
What it looks like
In the <head> of every page that has translated or localised variants:
<link rel="alternate" hreflang="en-us" href="https://example.com/en-us/page" />
<link rel="alternate" hreflang="en-gb" href="https://example.com/en-gb/page" />
<link rel="alternate" hreflang="pt-pt" href="https://example.com/pt/pagina" />
<link rel="alternate" hreflang="x-default" href="https://example.com/page" />
x-default is the fallback for users whose language/region doesn't match any specific variant.
The bidirectional rule
Every hreflang declaration must be reciprocal. If the English page declares the Portuguese version as an alternate, the Portuguese page must declare the English version as an alternate too. Missing reciprocals are the single most common hreflang bug and Google ignores broken sets.
Where to put it
Three valid placements, in roughly this order of preference:
- HTML
<head>— simplest, works for any HTML page. - HTTP header — for non-HTML resources (PDFs, etc.).
- XML sitemap —
<xhtml:link rel="alternate" hreflang="...">entries. Useful for very large sites where editing<head>is impractical.
Mix all three for the same set of URLs at your peril — Google sometimes treats conflicts as a reason to ignore the lot.
Common mistakes
- Wrong language codes: use ISO 639-1 (
en,pt) for language and ISO 3166-1 alpha-2 (US,GB) for region.en-ENis invalid; it should been-GB. - Mixing case wrong: spec says case-insensitive but lowercase is convention.
- Hreflang to noindex/blocked pages — Google ignores the whole set.
- Forgetting
x-defaultfor global users who don't match a specific locale. - No reciprocal — see above. The most common source of "we set up hreflang but it doesn't work."
Hreflang is for same-content, different-language variants. It is not for different products or significantly different content. Don't use it to consolidate ranking across two unrelated pages.