Implementing hreflang Correctly

Redaktion ·

If your site offers the same content in several languages or for several countries, Google faces a selection question: which variant should a user from Austria see, which one from the US? hreflang is the annotation that answers it. The strategic overview — ccTLD vs. subdirectory, geographic vs. linguistic targeting — is covered in the article International SEO. Here we deal with the mechanics: how to set up hreflang technically correct, without Google silently ignoring the whole set.

One thing up front, because it clears up the biggest misconception: hreflang is not a ranking signal. It doesn’t make a page “better” or push it higher. It’s a clustering and selection signal — it tells Google that several URLs are translations of the same page, and which variant fits which language/region setting. Google then ranks the variant suited to the user at the position the content would have earned anyway. Nothing more. And less, if the implementation is broken.

Three ways to deliver hreflang

There are exactly three places where hreflang may live. Functionally they’re equivalent — you choose by architecture, not by effect. Mixing them per URL set isn’t allowed; pick one path.

1. HTML <head> link tags. Each page carries, for each variant, a <link rel="alternate" hreflang="de-AT" href="…"> in the <head>. Advantage: easy to understand, visible directly in the HTML. Disadvantage: scales poorly. With 10 languages each page has 10 tags in the head, and every new language enlarges every head on every page. With many pages this quickly becomes a maintenance burden.

2. HTTP Link: header. The same information as an HTTP response header: Link: <url1>; rel="alternate"; hreflang="de-AT", …. The only path for non-HTML documents like PDFs, which have no <head>. Disadvantage: server-side configuration needed, harder to inspect.

3. XML sitemap with xhtml:link. The hreflang relationships sit centrally in the sitemap, each <url> entry lists its alternatives as <xhtml:link>. This is the best-scaling path for many pages: the markup lives in one place, the HTML head stays lean, and changes happen centrally instead of in every template. For large multilingual sites the default recommendation.

The return-tag principle: bidirectionality is mandatory

This is where most implementations fail — and it’s non-negotiable: hreflang annotations must be reciprocal. If page A points to page B, page B must point back to A. If it doesn’t, Google ignores the entire set, not just the faulty link. Google states it plainly: if two pages don’t point to each other, the tags are ignored.

Concretely this means: each page in the cluster lists all variants — including itself. A German page with three language versions therefore carries four hreflang entries: de, en, fr, and a self-reference to de. If a single page forgets the return link, the cluster collapses for that relationship. That’s exactly why the central sitemap variant is so popular: it makes it harder to forget a return link, because all relationships are defined in one place.

x-default: the fallback page

What happens to a user whose language setting matches none of your variants — say someone with a Japanese browser on your de/en/fr site? That’s what the special value hreflang="x-default" is for. It marks the fallback page: typically a language-selection page or the generic main version. x-default isn’t mandatory, but strongly recommended once your languages don’t cover the whole globe — which is practically always the case.

Setting the language-region codes correctly

hreflang values follow a fixed format, and typos here are one of the most common error sources:

  • Language alone: ISO 639-1, two letters — de, en, fr. The most common and often sufficient form when you only split by language, not region.
  • Language + region: ISO 639-1 plus ISO 3166-1 Alpha-2, separated by a hyphen — de-AT (German for Austria), en-US, en-GB, pt-BR. The region is always a country, not a language.
  • Script variants: ISO 15924, e.g. zh-Hans (simplified Chinese) vs. zh-Hant (traditional).

Two traps: region alone doesn’t work — hreflang="at" is invalid because at is read as a language code (which doesn’t exist). Region always needs a preceding language. And: en-UK is wrong — the ISO country code for Great Britain is GB, not UK.

The five most common errors

  1. Missing return links. The classic. A page points to its variants, but at least one doesn’t point back → Google ignores the set. Always keep all relationships bidirectional.

  2. Wrong codes. en-UK instead of en-GB, region without language, or non-ISO codes. Invalid values are silently discarded — no error in the frontend, but the markup has no effect.

  3. Mix of self-canonical and cross-locale canonical. The most dangerous conflict. Each locale must be self-canonical — the German page points, via its canonical tag, to itself, not to the English one. If you set the canonical of the de page to the en page, you tell Google simultaneously “this is an independent language variant” (hreflang) and “this is just a copy of the en page” (canonical). These contradictions cancel each other out and the cluster breaks. hreflang and canonical must never contradict each other.

  4. hreflang on noindex pages. A page set to noindex can’t be part of an hreflang set — Google removes it from the index and thus from the cluster, which tears the return-link chain. Use hreflang only on indexable pages.

  5. Conflict with canonical (the general form). Beyond special case 3: any canonical that points away from the annotated variant undermines the hreflang set. Rule of thumb — hreflang annotates variants, canonical decides about duplicates; don’t blend the two roles.

Debugging: how to spot errors

hreflang errors are insidious because nothing looks broken in the frontend — the page loads normally, only the international matching fails. Three tools help:

  • hreflang validators (external): feed in a URL and check whether all return links exist, codes are valid, and there are no canonical conflicts. The fastest reality check.
  • Google Search Console: the former “International Targeting” report is deprecated; current errors show up today in the index/page reporting and via URL inspection. Check there whether the right variant was chosen as canonical.
  • Crawlers (Screaming Frog & co.): crawl the whole site and list missing return links and invalid codes en masse — the path for large sites.

If you want to dig deeper into strategies for multi-locale setups, find them in the glossary under International SEO / hreflang strategies.

FAQ

Is hreflang a ranking factor? No. hreflang is a clustering and selection signal, not a ranking signal. It tells Google which URLs are translations of each other and which variant fits which user language. Google then ranks the matching variant at the position it earned anyway — hreflang ranks nothing higher.

Why does Google ignore my hreflang tags entirely? By far the most common cause: missing return links. If not all pages point to each other reciprocally (including a self-reference), Google discards the whole set. Second most common: invalid language codes or a canonical conflict where the locale isn’t self-canonical.

Which implementation method is the best? Functionally all three are equivalent. With many pages the XML sitemap variant scales best, because all relationships live centrally and the HTML head stays lean. HTML head tags are fine for small sites; HTTP headers you need for non-HTML documents like PDFs.

What is x-default for? x-default marks the fallback page for users whose language setting matches none of your variants — e.g. a language-selection page or the generic main version. Recommended once your languages don’t cover all possible user languages, which is practically always.

Must every language variant be self-canonical? Yes. Each locale must point, via canonical, to itself. If the canonical instead points to another language variant, it contradicts the hreflang signal — Google gets “independent variant” and “just a copy” at once and ignores the cluster. hreflang and canonical must never contradict each other.