What Is Hreflang? β Definition and How It Works
Learn how hreflang declares language and regional variants, the reciprocity rule, and how to use it for multi-locale collection.
hreflang annotations tell search engines that several URLs are language or regional variants of the same content, so the right one is shown to the right audience.
1. The Three Forms
In the HTML head:
<link rel="alternate" hreflang="en-gb" href="https://example.com/en-gb/product" />
<link rel="alternate" hreflang="en-us" href="https://example.com/en-us/product" />
<link rel="alternate" hreflang="de" href="https://example.com/de/produkt" />
<link rel="alternate" hreflang="x-default" href="https://example.com/product" />
As HTTP headers, for non-HTML resources.
In a sitemap, with xhtml:link entries β the most maintainable option for large sites.
2. The Value Format
language or language-region, using ISO codes:
| Value | Means |
|---|---|
en |
English, any region |
en-gb |
English, United Kingdom |
es-mx |
Spanish, Mexico |
pt-br |
Portuguese, Brazil |
x-default |
The fallback for unmatched audiences |
Common errors: using a country code as a language (uk is Ukrainian, not the United Kingdom), inventing codes, or omitting x-default so unmatched visitors have no designated page.
3. Reciprocity Is Required
The rule that most implementations break: every variant must link to every other variant, including itself.
If the English page lists the German one but the German page does not list the English one, the annotation is not trusted and is generally ignored entirely.
That makes hreflang a set that must be maintained coherently across all variants β which is why sitemap-based declaration is preferred at scale, since one file holds the whole set.
4. Why It Matters for Collection
This is the practically useful part. hreflang annotations are a published map of a site's locale variants β which saves discovering them by guesswork.
def locale_variants(doc, base_url):
out = {}
for link in doc.css('link[rel="alternate"][hreflang]'):
lang = link.attributes.get("hreflang", "").lower()
href = link.attributes.get("href")
if lang and href:
out[lang] = urljoin(base_url, href)
return out
From one page you learn every locale the site publishes and the exact URL for each. That is far more reliable than constructing locale URLs by pattern, which breaks whenever a site uses different slugs per language β as the /de/produkt example above does.
5. It Also Tells You What to Expect
The variant set is information about the site itself:
- Which markets it serves, which predicts currency and pricing variation.
- Whether regional variants exist within a language, implying price or availability differences between, say,
en-gbanden-us. - Which locale is the default, from
x-default.
For price or assortment collection across markets, that map is exactly the input needed β and collecting one locale while assuming it represents the others is a common source of wrong conclusions.
6. Hreflang Versus Canonical
They interact and are frequently confused:
- Canonical says "this URL is the primary version of this content".
- Hreflang says "these URLs are different-language versions of each other".
Each variant should be self-canonical β the German page canonicalises to itself, not to the English one. Canonicalising variants to a single language collapses them, which is the opposite of what hreflang is declaring.
Seeing variants all canonicalising to one URL is a misconfiguration worth noting rather than following.
7. Practical Notes
- Extract the variant map from any page you collect; it is free locale discovery.
- Do not construct locale URLs by pattern β slugs differ per language.
- Record which locale each record came from. Prices and availability differ.
- Check reciprocity if you rely on the annotations; a one-sided set may be incomplete.
- Pin
Accept-Languageto match the locale you intend, so content and annotation agree.
8. Summary
hreflang declares language and regional variants of the same content, in the head, in HTTP headers, or in a sitemap, using language-region codes plus an x-default fallback, and requires reciprocal links between every variant.
For collection its main value is as a published map of every locale a site serves and the exact URL for each β more reliable than guessing URL patterns β and each variant should be self-canonical, so variants collapsing to one canonical URL is a misconfiguration rather than a signal to follow.