Setting up hreflang: the four rules it always fails on

The customer in Dublin lands on the British page with the wrong currency, though the Irish version exists. What hreflang does about it, what it does not, and why one wrong canonical voids the lot.

11 minute readUpdated August 29, 2026Read in German

A customer in Dublin searches for your service, finds you, clicks, and lands on the British page with pounds, British VAT and a phone number nobody there wants to dial. The Irish version you built specially shows up nowhere. Or the other way round: a British visitor gets the German version of your home page even though the English one exists and is better.

Both are the same fault, and it has a name: Google does not know which of your language versions belongs to which person. This piece explains what hreflang does about that and what it explicitly does not (the difference is bigger than people expect), shows the four rules almost every implementation trips over, and says where to check for errors now that Google has retired the report that used to do it.

What hreflang does, and what it definitely does not

hreflang is a mapping. It tells Google: these pages are versions of the same content, this one is for German, this one for English, this one for English in Ireland. Google uses the mapping to show a searcher the version that fits.

Three misconceptions belong out of the way immediately:

It is not a ranking factor. A page does not rise because it carries hreflang. What changes is which of your pages gets shown, not what position it holds.

It does not open a new market. If you are invisible in Ireland, that is not down to missing markup but to having no page that matches those queries, or nobody knowing you. hreflang distributes visibility you already have; it does not create any.

It is not a remedy for duplicate content. The fact that your British and Irish versions are nearly identical is not resolved by hreflang. That is the canonical's job, and how the two interact is the most important section here. The groundwork is in canonical tags done right.

And it is a signal, not an instruction. Google may still show a different version if it decides that one fits better.

When you need it and when you do not

You need it in exactly three cases:

  • The same content in several languages.
  • The same language for different countries, when the content genuinely differs: prices, currency, shipping, legal text, contact person.
  • A selector page from which visitors pick their version.

You do not need it on a single-language site, not on pages that cover genuinely different things (those are not versions, they are separate pages), and not for the same language across several countries when the text is identical everywhere. That last point matters, because a lot of invented work lives there: three copies of the same text as en-GB, en-IE and en-AU cost you maintenance forever and do nobody any good. One version as en is enough.

The three ways to deliver it

All three are equivalent. You choose by scale and by who has access at your end.

In the page head. The usual route for sites with a manageable number of pages:

<link rel="alternate" hreflang="de" href="https://example.com/leistungen" />
<link rel="alternate" hreflang="en" href="https://example.com/en/services" />
<link rel="alternate" hreflang="x-default" href="https://example.com/leistungen" />

In the HTTP header. The only route for files with no head, meaning PDFs:

Link: <https://example.com/handbuch-de.pdf>; rel="alternate"; hreflang="de",
      <https://example.com/manual-en.pdf>; rel="alternate"; hreflang="en"

In the XML sitemap. The sensible route from a few hundred pages upwards, because the entries then live in one place instead of a thousand templates. More work to set up, considerably easier to maintain afterwards.

Pick one route and stay on it. Running head and sitemap side by side with entries that disagree is one of the reasons Google ends up discarding the markup entirely.

The four rules it fails on

One: self-reference. Every page has to list itself. A set of three versions carries all three entries on each of the three pages, including its own. Without the self-reference the set is incomplete.

Two: reciprocity. If the German page points to the English one, the English one has to point back. Without the return direction Google ignores the entry. This is the most common silent failure, and it typically happens when one language version is maintained by a different team or in a different system.

Three: absolute URLs. With the protocol, in full. Relative paths do not work here.

Four, and this is the killer: every page's canonical points at itself, never at another language version. Setting a canonical on the English page that points to the German one while also using hreflang sends two contradictory statements: "this is a version in its own right" and "this is a duplicate of the German page". Google resolves the contradiction by discarding the markup and deciding for itself. This combination is behind most cases of "hreflang does not work for us".

Language and region codes, where the typos live

The format is language, optionally a hyphen and a region. Language per ISO 639-1, region per ISO 3166-1 alpha-2.

rightwrongwhy
enen-US when there is only one English versionneedless narrowing, everyone outside the US is excluded
en-GBen-UKthe region code is GB, not UK
de-ATatthe first part must be a language, and "at" is not one
pt-BRbrsame pattern as at

The most common needless narrowing is a region code on a site that only has one version of that language. It says: for this country only. Everyone searching from anywhere else is explicitly not addressed. Use the bare language code until you genuinely run country-specific versions.

x-default, and what it is really for

x-default marks the version for everyone none of the others fit. Classically the selector page where someone picks their language. With no selector page you use whichever version is least wrong as a fallback.

It is not mandatory. And the widespread habit of pointing x-default at the English version is only right when English really is your fallback. If your business is German-speaking and English is the second language, x-default belongs on the German page.

Automatic redirection by IP: please do not

The obvious thought is to send visitors straight to the right version based on where they are. That creates two problems at once.

The crawler generally arrives from one country and then sees only one of your versions. It never finds the others, so it cannot show them either, and all your effort evaporates. And people who deliberately want a different version cannot get there: a German on holiday in Spain gets Spanish with no way out.

The right approach is to keep every version reachable at its own address, set hreflang cleanly, and offer the visitor a notice or a visible switcher. Suggest rather than redirect.

One detail from our own implementation

Traffalyzer runs German as the default language with no prefix and English under /en. That is a common build, and it has a trap that caught us out: the visible link from the English version back to the German one has to point at /de/..., not at the bare address. Otherwise the language detection sends a visitor whose stored preference is still English straight back into the English version, and the switcher goes round in circles.

The important part: this applies only to the clickable links in the page content. The canonical, the hreflang entries and the sitemap must keep naming the bare address, because that is the canonical one. Confusing the two leaves you with either a broken switcher or duplicate addresses in the index.

Where to check for errors now the report is gone

Plenty of guides still send you to the international targeting report in Search Console. It no longer exists; Google retired it. hreflang is still evaluated, there is simply no built-in error list for it any more.

What works instead:

  1. View the source of one page in each language version and check that every version including its own is listed.
  2. Check the return direction by hand: does the English page name the German one, and the German page the English one?
  3. Run a crawler over the site that outputs the entries as a table. Missing return directions stand out immediately.
  4. Use URL inspection to see which address Google treats as canonical. If it differs from the page itself, a canonical is usually set wrong, and then hreflang is out of force anyway.

What you cannot check is who Google shows which version to. There is no report for it, and searching yourself is no test, because it knows your location and your history.

Four failure patterns keep turning up in this check. Machine-translated versions with tidy markup: the markup is correct and the content is still weak. hreflang does not make a bad translation visible, it only files it correctly. Markup on addresses that are not the canonical ones: if your hreflang points at a parameter URL whose canonical names a different address, you are pointing at a page that, as far as Google is concerned, does not exist. A language version carrying noindex: it is then not a valid target and the set falls apart, and what else noindex does is in robots.txt and noindex. And entries forgotten after a relaunch that still point at old addresses, for which the checklist is in relaunch without losing traffic.

Where to start

  1. Decide whether you really need country versions or only language versions. When in doubt, language only.
  2. Check the canonicals first: every page at itself.
  3. Set hreflang with a self-reference on all versions, absolute URLs.
  4. Verify the return direction page by page, by hand for your ten most important pages.
  5. Point x-default at your real fallback version, not automatically at English.
  6. Switch off automatic redirection by location and build a visible switcher.
  7. Wait. The effect only shows once Google has recrawled every version.

Frequently asked questions

Do I need hreflang for a bilingual website?

Yes, as soon as the same content exists in two languages. Without the mapping, Google decides for itself which version to show to whom, and gets it wrong regularly, especially for users whose language and location do not match. The effort for two languages is small: two lines in each page head plus one for x-default.

Is hreflang a ranking factor?

No. It influences which of your versions gets shown, not what position it holds. Anyone hoping it brings more visibility in a new country will be disappointed: that takes content matching the queries there, and some prominence. The markup distributes visibility you already have, it does not generate any.

Should I use en or en-GB?

The bare language code, as long as you only have one English version. A region code says "for this country", which excludes everyone searching from elsewhere without gaining you anything. Country versions only pay off when the content genuinely differs, meaning prices, currency, shipping or legal text.

What is x-default and do I need it?

x-default marks the version for visitors none of your other entries fit. It is not mandatory but almost always sensible. Point it at your actual fallback: for a German-speaking business with English as a second language, that is the German page, not automatically the English one.

Why does Google ignore my hreflang?

Three causes cover it. First, a canonical pointing at a different language version rather than at the page itself, which is the most common. Second, a missing return direction because one version does not point back. Third, a target that is not indexable because it carries noindex, is blocked, or redirects.

Where do I check hreflang errors in Search Console?

Nowhere any more. The international targeting report was retired, though hreflang is still evaluated. You have to check it yourself: view the source, verify the return direction, or use a crawler that outputs the entries as a table. Guides still sending you to that report are out of date.

Can I redirect visitors automatically by location?

Better not. The crawler usually arrives from one country, then sees only one version and never finds the others. And people who deliberately want a different language cannot reach it. The better route is a notice or a visible switcher while every version stays reachable at its own address.

Does hreflang help against duplicate content?

No, these are two different tools. hreflang maps versions to each other; the canonical decides which address is authoritative when the content is the same. With nearly identical country versions of one language the similarity remains, which is exactly why such versions should only exist when they genuinely differ.

How many hreflang entries does a page need?

As many as there are versions, plus its own, plus optionally x-default. With three languages that is four lines on each of the three pages. From roughly a dozen versions or several hundred pages the head gets unwieldy, and then the entries belong in the XML sitemap.

Keep reading