hreflang Explained: A Practical Guide for Multilingual Sites

You translated your site, but Google keeps showing the English page to visitors in Vienna and the German page to people in Zurich who expected Swiss prices. That is the exact problem hreflang solves. In this guide you get a plain explanation of what hreflang does, copyable code for the three ways to add it, a look at how WordPress, Shopify and Webflow handle it and a checklist of the mistakes that break most setups.

What hreflang actually does

hreflang is an annotation that tells search engines “this page has equivalents in other languages or regions and here they are.” Google uses it to swap in the right URL for each searcher. According to Google Search Central’s guide to localized versions, Google can sometimes find your alternate versions without help, but it still recommends you mark them explicitly.

Two things hreflang does not do are worth knowing up front. First, it does not tell Google what language a page is in. Google’s documentation states that it detects language with its own algorithms and ignores both hreflang and the HTML lang attribute for that purpose. Second, it does not redirect anyone. It only influences which URL appears in search results.

It also helps with a worry many site owners have: duplicate content. Google’s same guide explains that localized pages only count as duplicates when the main content stays untranslated. A properly translated page is its own page.

The building blocks: language and region codes

Every hreflang value starts with a language code in ISO 639-1 format, such as de, fr or en. You can optionally add a region code in ISO 3166-1 Alpha 2 format after a hyphen, which gives you values like de-AT (German for Austria) or en-GB (English for the United Kingdom).

A few rules from Google’s documentation trip people up constantly:

  • A region code on its own is invalid. be is read as Belarusian, not Belgium.
  • The United Kingdom is GB, not UK. Codes like UK, EU or UN are wrong and Google ignores that part of the annotation.
  • Script variants are allowed, for example zh-Hans for Simplified Chinese and zh-Hant for Traditional Chinese.
  • Codes outside these standards, such as es-419 for Latin American Spanish, are not supported by Google.
  • x-default is a special value that needs no language code.

If you only have one German version for everyone, use plain de. Add regions only when the content really differs, for example different prices, currencies or shipping rules.

Three ways to add hreflang (with code)

Google treats all three methods as equivalent and says that using more than one brings no extra benefit. Pick the one that fits your stack and stick with it.

This is the most common option for small sites. Each language version gets the same block of tags in its <head>. Every block lists all versions, including the page itself.

<head>
  <link rel="alternate" hreflang="en" href="https://example.com/en/pricing/" />
  <link rel="alternate" hreflang="de" href="https://example.com/de/preise/" />
  <link rel="alternate" hreflang="de-AT" href="https://example.com/at/preise/" />
  <link rel="alternate" hreflang="fr" href="https://example.com/fr/tarifs/" />
  <link rel="alternate" hreflang="x-default" href="https://example.com/en/pricing/" />
</head>

Notice that the URLs are fully qualified, including https://. Google’s documentation requires this; relative paths like /de/preise/ are not valid here. Alternate URLs may sit on different domains, so example.de and example.fr can point at each other.

Method 2: HTTP headers for PDFs and other files

Non-HTML files have no <head>, so you send the same information in an HTTP Link header. This is handy if you publish price lists or manuals as PDFs in several languages.

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

You configure this on the server (for example in Nginx, Apache or your CDN), not in the file itself.

Method 3: the XML sitemap

On larger sites, adding tags to every template gets messy. The sitemap method keeps all annotations in one file. Each <url> entry has its own <loc> and then lists every variant, itself included, as <xhtml:link> children. Do not forget the xmlns:xhtml namespace declaration at the top.

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
        xmlns:xhtml="http://www.w3.org/1999/xhtml">
  <url>
    <loc>https://example.com/en/pricing/</loc>
    <xhtml:link rel="alternate" hreflang="en" href="https://example.com/en/pricing/" />
    <xhtml:link rel="alternate" hreflang="de" href="https://example.com/de/preise/" />
    <xhtml:link rel="alternate" hreflang="x-default" href="https://example.com/en/pricing/" />
  </url>
  <url>
    <loc>https://example.com/de/preise/</loc>
    <xhtml:link rel="alternate" hreflang="en" href="https://example.com/en/pricing/" />
    <xhtml:link rel="alternate" hreflang="de" href="https://example.com/de/preise/" />
    <xhtml:link rel="alternate" hreflang="x-default" href="https://example.com/en/pricing/" />
  </url>
</urlset>

Google notes that these xhtml:link child elements do not count toward the sitemap’s URL limit and that a sitemap can only list URLs from its own directory and below.

Which method should you choose?

Here is a quick comparison based on Google’s documentation and the practical trade-offs for small teams.

Method Best for Where you edit it Main drawback
HTML link tags Most CMS sites and hand-coded pages Page template <head> Adds markup to every page; easy to forget on new templates
HTTP header PDFs and other non-HTML files Server or CDN config Needs server access; invisible in page source
XML sitemap Large sites, shops with many products One sitemap file Harder to spot errors by viewing a page

For a typical business site, HTML tags generated by your CMS or plugin are the simplest route. A sitemap starts to pay off once you manage hundreds of product pages per language, because one file is easier to audit than hundreds of templates.

What x-default is for

x-default names the page users should see when none of your language or region versions match them. Google suggests a language picker or an auto-redirecting homepage as typical targets. In practice many sites simply point it at their main language version, as in the examples above.

It is optional, but skipping it is the single most common gap. In Ahrefs’ study of 374,756 domains using hreflang, 56.3% were missing x-default.

The mistakes that break hreflang

That same Ahrefs study found that 67% of domains using hreflang had at least one issue. The most frequent ones after missing x-default were:

  1. Missing self-referencing tags (18% of domains). Every page must list itself as well as its alternates.
  2. Links to redirected or broken pages (16.9%). If you change a URL, update the hreflang targets too.
  3. Missing return links (15.3%). If your English page points to the German one, the German page must point back. Google’s documentation warns that one-way annotations may be ignored.
  4. Pointing to non-canonical URLs (8%). hreflang should only reference the canonical version of each page.
  5. Incorrect hreflang values (4.6%), usually the code errors described above.

The canonical issue deserves a closer look. Ahrefs’ hreflang guide explains that when hreflang points at a URL whose canonical tag names a different page, the two signals contradict each other and confuse search engines. The rule of thumb: each language version should carry a self-referencing canonical. Then point hreflang at exactly those URLs.

One more practical point: Google retired the International Targeting report in Search Console, which used to flag hreflang errors. Its help page on the deprecation confirms that Google continues to support and use hreflang tags. You now check them with crawlers, validators or by reading your page source.

You often do not have to write these tags by hand.

Shopify creates hreflang tags automatically for every international domain or subfolder you set up in Markets, according to the Shopify Help Center. You can switch this off under Online Store > Preferences, but Shopify warns that you then need to add your own tags to the theme. Do not add a second set on top of the automatic one.

Webflow generates hreflang for its Localization feature, either as page-level tags or in the auto-generated sitemap, as described in Webflow’s help article on localized SEO. If you use a custom sitemap instead, you have to add the annotations yourself.

WordPress has no built-in multilingual support, so hreflang comes from your translation plugin. Check what your plugin outputs by viewing the page source and searching for hreflang. If you run a plugin and an SEO plugin side by side, make sure only one of them prints the tags.

Custom HTML sites need the tags in your templates or a sitemap. A clean language menu helps users switch versions too; our language switcher code generator gives you a starting point.

What about Bing?

Bing is the exception. Ahrefs’ hreflang guide describes hreflang as a weak signal for Bing, which relies mainly on the content-language attribute, links and visitor data. The same guide notes that Yandex reads hreflang while Baidu does not. Bing’s own webmaster blog post from 2011 recommends the content-language meta tag with a language and country code:

<meta http-equiv="content-language" content="de-at" />

Adding this alongside hreflang does no harm and covers Bing’s preferred signal. Keep the value consistent with your <html lang> attribute so the signals agree.

FAQ

Do I need hreflang if my site only has one language?

No. hreflang describes relationships between equivalent pages in different languages or regions. With a single version there is nothing to annotate.

Does hreflang improve my rankings?

Not directly. It helps Google show the right language version to the right searcher, which can improve clicks and reduce bounces from people who land on a page they cannot read. It does not boost a page that would not rank anyway.

Should I use both HTML tags and a sitemap?

Google says the methods are equivalent and using more than one gives no extra benefit. Using two also doubles the places where errors can creep in, so choose one.

Can hreflang point to a page on another domain?

Yes. Google explicitly allows alternate URLs on different domains, so example.de and example.com/en/ can reference each other as long as both sides link back.

How do I check if my hreflang works?

Open a page, view the source and confirm every version is listed with full URLs, including the page itself and x-default. Then open one of the alternates and confirm it lists the same set. A site crawler can do this at scale.

Conclusion

hreflang is simple in principle and fiddly in practice. Every version lists every version, including itself; every link is answered by a return link; codes follow ISO standards; and all targets are canonical, live URLs. Add x-default and you already avoid the most common gap from the Ahrefs data. Start by viewing the source of your most important page in each language today, because that five-minute check catches most problems.

If you still need the translations themselves, heylingo adds AI translation with translation memory to your site through one script tag, lets you correct texts inline on the live site and covers 30+ languages for EUR 20 per 1,000,000 translated characters per month. The hreflang setup stays with your CMS, plugin or developer.

See heylingo pricing and start translating your site

Sources

JE

Written by

Jermaine builds and runs heylingo single-handedly from Germany and answers every support email personally.

More from the blog