⌕ Technical SEO

Hreflang: how to connect the language versions of a site

How hreflang annotations work: language and country codes, return links and x-default, plus the most common mistakes and a method for checking them.

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-UK instead of en-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

  1. Missing return links between pairs of pages.
  2. A page that does not list itself among the alternatives.
  3. Wrong codes, such as en-UK or it_IT.
  4. URLs that redirect or return 404.
  5. All versions point to the home page of each language instead of the equivalent page.
  6. 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, not en-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.
MM
Marco Marzaduri

Marco Marzaduri works in cybersecurity, digital forensics and web development. A computer science graduate, he combines rigorous technical analysis with attention to the people who use technology.

Read also