When a site exists in several languages, or in the same language for different countries, the search engine has to work out which version to show to whom. The hreflang attribute exists precisely for this: it says "this page has equivalent alternatives, and this is the language (and sometimes the country) of each one". It is not a ranking signal, it is a substitution signal: it helps show the right version in place of the wrong one.
What it solves and what it doesn't
Hreflang is useful in two typical cases:
- the same content translated into several languages (Italian, English, German);
- very similar content in the same language for different markets, for example English for the United Kingdom and the United States with different prices, currencies or shipping.
It does not, however, solve indexing problems: if a version is not indexed, hreflang will not get it into the index. And it does not replace a good translation: a poor, machine-translated page stays poor even when annotated correctly.
The codes: language first, country second
The hreflang value is a language code in ISO 639-1 format, optionally followed by an ISO 3166-1 alpha-2 country code:
| Value | Meaning |
|---|---|
it |
Italian, for any country |
it-CH |
Italian for Switzerland |
en-GB |
English for the United Kingdom |
en-US |
English for the United States |
x-default |
default version when none matches |
Frequent code mistakes:
- using
en-UKinstead ofen-GB: the United Kingdom's code is GB; - giving only the country, such as
ch, which would be read as a nonexistent or different language; - using an underscore, as in
it_IT, which is the notation of software locales but not the expected one.
The country cannot be specified on its own: the language is always required.
Three ways to declare it
In the page head
This is the most common method. Each page lists all of its alternatives, including itself:
<link rel="alternate" hreflang="it" href="https://example.com/it/prezzi/" />
<link rel="alternate" hreflang="en" href="https://example.com/en/pricing/" />
<link rel="alternate" hreflang="x-default" href="https://example.com/en/pricing/" />
In the HTTP header
For files that are not HTML, such as PDFs, you use the Link header with the same logic.
In the XML sitemap
Each <url> element contains a series of xhtml:link entries with the alternatives. It is the cleanest solution for large sites, because it takes weight off the HTML and centralises management, but it requires the sitemap to be generated reliably.
It is best to choose a single method. Using two is not forbidden, but it doubles the places where the information can diverge.
The return rule
Annotations must be reciprocal. If the Italian page lists the English version as an alternative, the English page must list the Italian one. A link without a return is ignored, because otherwise anyone could declare themselves an alternative of someone else's page.
In my work this is the most frequent cause of errors: a translation added later that points to the original, while the original was never updated.
X-default
x-default indicates the page to show when the user's language or country matches none of the versions. It is usually:
- a language selection page;
- or the main version, often the English one.
It is not mandatory, but on sites with an international audience it prevents speakers of an unsupported language from landing on a random version.
Hreflang and canonical must agree
Each language version must have a canonical pointing to itself, not to the main version. If the English page declares the Italian one as canonical, it is telling the engine to disregard it, and the hreflang annotation loses its meaning.
In addition, the URLs listed in hreflang must be:
- the canonical ones, not variants with parameters;
- reachable with a 200 response;
- indexable, so without noindex and not blocked by robots.txt.
The most common mistakes
- Missing return links between pairs of pages.
- A page that does not list itself among the alternatives.
- Wrong codes, such as
en-UKorit_IT. - URLs that redirect or return 404.
- All versions point to the home page of each language instead of the equivalent page.
- Cross-language canonicals pointing to another language.
How to check it
- A desktop crawler with hreflang checking enabled reports missing returns, invalid codes and non-indexable URLs.
- Search engines' webmaster tools show how canonical pages are chosen for each version.
- For a quick check on individual pages, just open the source and compare the list of alternatives across the different versions: they must be identical.
When there are many versions, it is better to generate the annotations from a single correspondence table in the CMS or build system, rather than writing them by hand page by page.
In short
- Hreflang indicates the equivalent versions of a page in other languages or countries.
- The code is ISO 639-1 language, with optional ISO 3166-1 country:
en-GB, noten-UK. - Each page lists all alternatives, including itself, and the links must be reciprocal.
- Each version has a canonical pointing to itself, never to another language.
- Generate annotations from a single source and check them with a crawler.