Skip to content

SEOPart of: International SEO

hreflang: what it is and how to implement it

hreflang tells Google which language or country version of a page to show each searcher. The syntax, the three places it can live, working examples and the rules that make it count.

getReport teamUpdated 26 Sept 202614 min read

hreflang is an annotation that tells Google a page has versions in other languages or for other countries, and which version to show each searcher. You add it as <link rel="alternate" hreflang="de" href="…"> tags in the page head, as an HTTP Link header or in your XML sitemap, and every version must list every other version and itself. Get those rules right and a German speaker in Vienna sees your German page instead of the English one.

This is the complete reference for whoever builds or maintains a multilingual site: the syntax, valid codes, where the tags can live, and how to implement them without errors. hreflang is one part of international SEO: site structure, hreflang and language targeting, which covers the strategy and URL structure decisions that come first.

Quick answer

  • One tag per version, on every version. Each page lists all its language or country versions, itself included, with rel="alternate", an hreflang code and a full URL.
  • Codes: an ISO 639-1 language (de), optionally with an ISO 3166-1 alpha-2 region (de-AT). Not en-UK, not en_GB, not a region on its own.
  • Add one x-default for searchers none of your versions fits, usually the international English page or a language picker.
  • Full URLs that answer 200. https:// included, no redirects, no 404s, and each URL the canonical of its version.
  • Pick one place: tags in the <head>, HTTP headers or the XML sitemap. Google reads all three, but there is no benefit in combining them.
  • Every link must be returned. If page A lists page B, page B must list page A, or Google ignores the pair.

What is hreflang?

hreflang is the value of a rel="alternate" link that names the language, and optionally the country, of another version of the same page. Google documents it in Tell Google about localized versions of your page on Search Central, which this guide follows.

Its job is narrow. When several versions of a page could answer a search, hreflang tells Google which one to show for which language and region. It does not make a page rank higher, and Google says it does not use hreflang or the HTML lang attribute to detect a page's language: it reads the visible text for that. So hreflang swaps the right version into results for a page that already ranks.

Why hreflang matters for SEO

Without hreflang, Google picks a version itself, and it often picks the one with the most links, usually the English or home-market page. The Austrian searcher lands on the German-German page with the wrong prices, or the US searcher sees pounds sterling. They go back to the results, and you lose the sale even though you had the right page.

hreflang also helps with same-language regional versions. An en-GB and an en-US page with nearly identical text can be folded together as duplicates, but with a correct set Google still shows each searcher the local URL.

hreflang syntax: the anatomy of a tag

A single hreflang tag in HTML has three parts:

HTML
<link rel="alternate" hreflang="de-AT" href="https://example-shop.hr/at/taschen/" />
  • rel="alternate" says the URL is another version of this page.
  • hreflang="de-AT" names its language (de, German) and region (AT, Austria).
  • href is the fully qualified URL of that version, with the protocol.

Valid language and region codes

The language is an ISO 639-1 two-letter code. The region, when you need one, is an ISO 3166-1 alpha-2 code after a hyphen. Google's documentation adds ISO 15924 script codes for languages written in more than one script, such as zh-Hans and zh-Hant.

CodeMeansValid?
enEnglish, any regionYes
en-GBEnglish, United KingdomYes
en-UKUK is reserved, not the ISO code for the United KingdomNo, Google ignores it; use en-GB
en_GBUnderscore instead of hyphenNo
gbA region with no languageNo, Google does not infer the language from a country
es-419Spanish, Latin America (a UN M.49 area code)No, Google names it as unsupported; use one code per country
zh-Hant-TWChinese, traditional script, TaiwanYes

Codes are case-insensitive, so de-at works, but the convention is lowercase language and uppercase region. Language-only codes are usually the better default: use a region only where something really differs, such as price, currency, stock or legal terms.

x-default

x-default is a reserved value for the page to show when no version matches the searcher's language or region. It is optional but recommended, used once per set, and listed on every version like the others:

HTML
<link rel="alternate" hreflang="x-default" href="https://example-shop.hr/en/bags/" />

Point it at your international English page or a language picker. x-default explained covers which page to choose and the redirect mistake that breaks it.

A complete hreflang example

Here is a full set for a shop with a Croatian, an English and a German version of the same category page, plus x-default. The same five lines go in the <head> of all three pages:

HTML
<link rel="alternate" hreflang="hr" href="https://example-shop.hr/torbe/" />
<link rel="alternate" hreflang="en" href="https://example-shop.hr/en/bags/" />
<link rel="alternate" hreflang="de" href="https://example-shop.hr/de/taschen/" />
<link rel="alternate" hreflang="de-CH" href="https://example-shop.hr/ch/taschen/" />
<link rel="alternate" hreflang="x-default" href="https://example-shop.hr/en/bags/" />

Three things make this set work. Each page lists itself, so the Croatian page includes its own hr line. The lists are identical on every page, so every link is returned. And de plus de-CH means Swiss German speakers get the Swiss page with francs, while German speakers everywhere else get the general German page.

Where to put hreflang: HTML, HTTP header or sitemap

Google treats the three methods as equivalent. Choose the one you can keep consistent, and use only one per set.

In the HTML head

The <link> tags must sit inside a well-formed <head>. Markup that is invalid in the head, such as an <img> or a stray <div> injected by a script, makes parsers close the head early, and any tag after it no longer counts. Put hreflang high in the head and, as Google suggests, paste the rendered page into an HTML validator if in doubt. Keep one version per <link>, and don't combine hreflang with other attributes such as media in the same tag. This method suits most sites up to a few thousand pages, and multilingual plugins use it.

For PDFs and other files with no HTML head, send the set as a Link response header, one comma-separated entry per version:

HTTP
Link: <https://example-shop.hr/katalog.pdf>; rel="alternate"; hreflang="hr",
      <https://example-shop.hr/en/catalogue.pdf>; rel="alternate"; hreflang="en",
      <https://example-shop.hr/de/katalog.pdf>; rel="alternate"; hreflang="de"

Each file in the set must send the full header, including its own entry.

In the XML sitemap

The sitemap method adds xhtml:link children to each <url>. Every URL gets its own <url> entry, and each entry repeats the whole set, itself included. The xmlns:xhtml namespace must be declared on <urlset>:

XML
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
        xmlns:xhtml="http://www.w3.org/1999/xhtml">
  <url>
    <loc>https://example-shop.hr/torbe/</loc>
    <xhtml:link rel="alternate" hreflang="hr" href="https://example-shop.hr/torbe/" />
    <xhtml:link rel="alternate" hreflang="en" href="https://example-shop.hr/en/bags/" />
    <xhtml:link rel="alternate" hreflang="de" href="https://example-shop.hr/de/taschen/" />
  </url>
  <!-- then one <url> for /en/bags/ and one for /de/taschen/, each with the same three lines -->
</urlset>

The sitemap keeps large sites consistent because one generator writes every set, and it keeps page weight down when a page has dozens of versions. hreflang in sitemaps vs in HTML compares the two in detail and shows how to move from one to the other without a period where they disagree.

How to implement hreflang step by step

  1. List your versions. Make a table with one row per page and one column per version: the language or language-region code at the top, full URLs in the cells. Leave a cell empty where a page has no translation; never fill it with the home page.
  2. Settle URLs and canonicals first. Each version needs its own crawlable URL and a canonical tag pointing at itself. hreflang lists those same canonical URLs.
  3. Generate the tags from the table. Hand-written sets drift as soon as two people edit two languages. Let your CMS, plugin or sitemap generator write them, or paste the table into the generator below.
  4. Add x-default to every set, pointing at the same fallback page everywhere.
  5. Deploy to all versions at once. A set published on the English pages but not yet on the German ones has no return links, and Google ignores it.
  6. Check one page per template in each language, then watch Search Console's performance report filtered by country over the following weeks.

The generator takes that table and returns the complete set for every page as HTML tags, an XML sitemap or HTTP headers. It names each code as you type (de-AT becomes "German (Austria)"), flags mistakes such as en-UK and en_US, and reports relative URLs or a page that appears in two rows. It runs in your browser and never visits the URLs, so it cannot tell you whether a version is live.

Platform notes

WordPress

WPML, Polylang, TranslatePress and Weglot print hreflang tags for the translations they manage. Check the page source before adding anything by hand; two sources on one page usually disagree. Multilingual WordPress: WPML, Polylang and hreflang covers each plugin's settings and typical failures.

Shopify

Shopify creates hreflang tags automatically for every international domain or subfolder you set up in Markets, and its help centre says the set includes an x-default pointing at your primary domain. You can turn the automatic tags off under Online Store > Preferences, but only do that if a theme or app will print a complete set instead; otherwise you have none. Check that every market you publish is one you really serve, because each adds a version to every page's set.

Custom sites and headless setups

Keep one source of truth for which URLs are versions of each other, usually a translation key or a shared ID in the CMS. Generate either the head tags or the sitemap from it, never both by hand.

How to check your hreflang tags

Mistakes in hreflang are silent: the page looks fine, and Google quietly ignores the set. Test from outside, the way Google reads it.

The checker reads every hreflang tag in the page's HTML, validates the codes, checks for a self-reference, duplicates and at most one x-default, then fetches up to 50 alternates to confirm each answers and links back. It does not read sets declared only in a sitemap or HTTP headers. The same findings appear in the SEO module of every getReport report:

hreflang best practices and common mistakes

  • Missing return links. The most common error. Hreflang return links shows how they break and how to see the whole matrix at once.
  • No self-reference. A page that lists only its other versions breaks the set.
  • Invalid codes. en-UK, en_GB, jp instead of ja, es-LA meant as Latin America (LA is Laos).
  • Alternates that redirect or 404. Drop versions you no longer publish, and update URLs after a migration.
  • Canonicals across languages. A German page whose canonical points at the English page tells Google it is a duplicate, and its hreflang is then ignored.
  • Untranslated pages in the set. Listing a page that is still in English as the de version sends German speakers to English text.
  • Relying on hreflang for language detection. Google reads the visible text. The page still needs real content in its language, and the right lang attribute for browsers and screen readers.

hreflang and the lang attribute do different jobs. hreflang links versions for search engines; <html lang="de"> tells browsers, translation tools and screen readers what language the page is in. Language attributes and screen readers covers the values and where they go.

Questions people ask

What is hreflang in SEO?

hreflang is an attribute on rel="alternate" links that tells search engines a page has versions in other languages or for other countries. Google uses it to choose which version to show each searcher, for example the Austrian page for someone searching in German from Austria. It does not raise rankings; it swaps the right version of a page into results where the page already ranks.

Does hreflang improve rankings?

No, not directly. hreflang does not add ranking strength; it tells Google which version of a page to show once that page ranks. The effect you see is the right page for each market: local prices, the right language and fewer visitors bouncing back to the results. Rankings in a new market still depend on localised content and links from that market.

Where do hreflang tags go in the HTML?

Inside the <head> of every language version, as <link rel="alternate" hreflang="…" href="…"> elements. Put them high in the head, before anything that could make a parser end the head early, because Google reads them only inside a well-formed <head>. Each version carries the full set, itself included. Files without HTML use an HTTP Link header, and large sites can use the XML sitemap instead.

Is hreflang case-sensitive?

No. Google treats de-AT, de-at and DE-AT the same. The convention is a lowercase language code and an uppercase region code, which is also how most generators and plugins write them. What does matter is the separator and the codes themselves: a hyphen, never an underscore, and GB rather than UK for the United Kingdom.

Does Bing support hreflang?

Not as its main signal. Bing's published advice has pointed to the content-language meta tag and the HTML lang attribute to understand a page's language and region, along with the domain and server location. Keep hreflang for Google and set an accurate lang attribute on every version, which also helps browsers and screen readers. Adding a content-language meta tag with the same value does no harm.

Does Shopify add hreflang tags automatically?

Yes. Shopify creates hreflang tags for every international domain or subfolder you set up in Markets, and you can turn the automatic tags off under Online Store > Preferences. Leave them on unless a theme or app prints a complete set instead, and avoid running both. Publish only the markets you really serve, since every market adds a version to each page's set.

Do I need hreflang for a site in one language?

No. hreflang only links versions of the same page in different languages or for different regions. A site with one language and one market has nothing to link, so the tags add nothing. Set the right lang attribute on the <html> element instead. Add hreflang when you publish a second language or a separate country version.

Check your site before and after Check