Audit my site
Technical SEOIntermediateChecked against Google docs · Oct 2026

hreflang: how to tell Google about language and regional versions of a page

hreflang connects the language and regional versions of a page so Google can show each searcher the right one. It only works when every version lists every other, each link is returned, and the codes and URLs are valid.

Author: Eugene Serbin, Head of SEO at Semalt Updated: 30 October 2026 Reading time: 20 min Visuals: 4

In short

hreflang tells Google that several URLs are language or regional versions of the same page, so it can show each searcher the right one. Every version must list itself and all the others with full URLs, and every pair must link both ways, or Google ignores the unpaired links. You can declare the set in HTML, in an HTTP header or in your XML sitemap; pick one method, use valid codes and keep each version as its own canonical.

What hreflang does and when to use it

hreflang is an annotation that connects alternate versions of a page. It says: “this URL is the German version, that one is for English speakers in the UK, and this one is the fallback for everyone else”. Google can then show the British page to a searcher in the UK and the German page to a German speaker, instead of whichever version happens to be strongest.

Google lists three situations where you should mark up alternate versions:

Google separates two kinds of international site. A multilingual site offers content in more than one language, such as a Canadian business with English and French pages. A multi-regional site explicitly targets users in different countries, such as a manufacturer that ships to Canada and the United States. Many sites are both. hreflang handles both cases, because each value can name a language, or a language plus a region.

What hreflang does not do

Diagram · One hreflang cluster with return links
Four versions of one page linked by hreflang Four URLs form one cluster: hreflang en at https://example.com/en/, en-GB at https://example.com/en-gb/, de at https://example.com/de/ and x-default at https://example.com/. Every pair is connected by arrows in both directions, and every version also lists itself. hreflangcluster hreflang="en" hreflang="en-GB" hreflang="de" hreflang="x-default" https://example.com/en/ https://example.com/en-gb/ https://example.com/de/ https://example.com/ lists all 4 URLs, itself included lists all 4 URLs, itself included lists all 4 URLs, itself included country selector, the fallback
Each line is a pair of return links: a link counts only if the target links back. Every page carries the same four annotations.

What Google officially says

“If you have multiple versions of a page for different languages or regions, tell Google about these different variations. Doing so will help Google Search point users to the most appropriate version of your page by language or region.”

Google Search Central — Tell Google about localized versions of your page

“If two pages don't both point to each other, the tags will be ignored.”

Google Search Central — Tell Google about localized versions of your page. The reason: “someone on another site can't arbitrarily create a tag naming itself as an alternative version of one of your pages.”

More direct quotes from the same documentation:

Language and region codes

An hreflang value has one part, or two parts separated by a hyphen. The first part is always the language, in ISO 639-1 format. The optional second part is the region, in ISO 3166-1 Alpha 2 format. Google is strict about the standards: “Only language codes listed in ISO 639-1 and region codes listed in ISO 3166-1 Alpha 2 are supported; other codes that aren't listed in those standards, such as es-419, aren't supported.”

“The hreflang value is case-insensitive”, so en-gb and en-GB mean the same. Writing the region in capitals follows the ISO convention and is easier to read. Use a hyphen, not the underscore that many CMS locale settings use (en_GB).

The most important rule: “You can't specify the country code by itself.” Google “doesn't automatically derive the language from a country code.” Google's own example is Belgium. To reach Dutch, French and German speakers there, you use nl-BE, fr-BE and de-BE. A plain be is wrong, because be is the language code for Belarusian.

Reserved or invented region codes do nothing. Google says “using EU, UN, or UK in hreflang annotations doesn't have an effect on Google Search”. The United Kingdom is GB, so the correct value is en-GB, never en-UK.

For languages written in more than one script, the script is normally derived from the region: zh-TW implies Traditional Chinese. You can also name the script with an ISO 15924 code: zh-Hant (Traditional), zh-Hans (Simplified), or with a region, zh-Hans-US.

ValueVerdictWhy
de✓ ValidGerman, any region
en-GB✓ ValidEnglish for users in the United Kingdom
de-ES✓ ValidGerman for users in Spain; any valid language-region pair works
zh-Hant✓ ValidChinese, Traditional script
en-UK✕ Region ignoredUK is not the ISO code; use en-GB
en-EU✕ Region ignoredEU is reserved, not a country
es-419✕ Not supportedNot an ISO 3166-1 Alpha 2 region
be for Belgium✕ WrongMeans Belarusian; use nl-BE, fr-BE, de-BE
jp, dk, se✕ WrongCountry codes used as languages; Japanese is ja, Danish da, Swedish sv
ua, gr✕ WrongUkrainian is uk, Greek is el
en_GB✕ Wrong formatUse a hyphen: en-GB

The rules every hreflang set must follow

The three methods differ in where the annotations live, but the rules are the same for all of them.

  1. Self-reference. “Each language version must list itself as well as all other language versions.”
  2. An identical set everywhere. “The set of links is identical for every version of the page.” If you have five versions, each of the five carries the same five annotations.
  3. Return links. If page X names page Y, page Y must name page X. Annotations without a return link are ignored. Google adds that if a complete set is hard to maintain, “you can omit some languages on some pages; Google will still process the ones that point to each other.” Its advice is to link new language versions to your original, strongest language first.
  4. Fully-qualified URLs. “Alternate URLs must be fully-qualified, including the transport method (http/https)”: https://example.com/de/, not //example.com/de/ or /de/.
  5. Any domain. “Alternate URLs do not need to be in the same domain.” example.de and example.com/en/ can be in one set.
  6. HTTPS. Google's canonical documentation says: “Don't include the HTTP version of your pages in your sitemap or hreflang annotations rather than the HTTPS version.”
  7. A catch-all for each language. If you have English pages for Ireland (en-IE), Canada (en-CA) and Australia (en-AU), Google suggests you “provide a generic English (en) page for searchers in the US, UK, and all other English-speaking locations.” It can be one of the regional pages.
  8. Healthy targets. In practice, every URL in the set should return 200, be indexable, not be blocked in robots.txt, not redirect, and be the canonical URL of that version. A target that fails any of these cannot send a valid return link.
Code · Wrong vs correct, on https://example.com/de/

✕ Broken set

<head>
  <link rel="canonical"
    href="https://example.com/en/">
  <link rel="alternate" hreflang="en-UK"
    href="https://example.com/en-gb/">
  <link rel="alternate" hreflang="en"
    href="/en/">
  <!-- no line for the de page itself -->
</head>
  • Canonical to another language
  • UK is not a region code
  • Relative URL
  • No self-reference, no x-default

✓ Correct

<head>
  <link rel="canonical"
    href="https://example.com/de/">
  <link rel="alternate" hreflang="de"
    href="https://example.com/de/">
  <link rel="alternate" hreflang="en-GB"
    href="https://example.com/en-gb/">
  <link rel="alternate" hreflang="en"
    href="https://example.com/en/">
  <link rel="alternate" hreflang="x-default"
    href="https://example.com/">
</head>
  • Self-referencing canonical
  • Valid ISO codes
  • Absolute HTTPS URLs
  • Lists itself, all versions and x-default
The left version breaks four rules at once; the canonical alone tells Google to treat the German page as a duplicate of the English one.

Method 1: HTML link elements

Add one <link rel="alternate" hreflang="…" href="…"> element per version to the <head> of every version, including the page's own line. This is the usual choice when you do not have a sitemap or cannot set HTTP headers.

Two technical rules matter. “The <link> tags must be inside a well-formed <head> section of the HTML.” A stray element in the head, such as an <img> or a <div> injected by a script, can make the browser close the head early, and every hreflang link after it then lands in the body. And “don't combine hreflang annotations with other attributes such as media in a single <link> tag.”

A site with a generic English page, a UK page, a US page, a German page and a selector page would put this block in the head of all five:

<link rel="alternate" hreflang="en-GB" href="https://example.com/en-gb/page/" />
<link rel="alternate" hreflang="en-US" href="https://example.com/en-us/page/" />
<link rel="alternate" hreflang="en"    href="https://example.com/en/page/" />
<link rel="alternate" hreflang="de"    href="https://example.com/de/page/" />
<link rel="alternate" hreflang="x-default" href="https://example.com/" />

Keep the block in the HTML your server sends. Tags added or changed by JavaScript only exist after rendering, and when the raw and rendered HTML disagree you are sending two different sets.

The same set can travel in the HTTP response. Google notes: “This is useful for non-HTML files (like PDFs).” A PDF has no <head>, so the server sends a Link header with all versions, separated by commas:

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

Each URL sits inside angle brackets. “The Link: header returned for every version of a page is identical”, so all three PDFs return exactly this header. You set it in the web server or CDN configuration, which also makes it the easiest method to forget about when files move.

Method 3: XML sitemap

In a sitemap, each version gets its own <url> entry with a <loc>, and each entry carries one <xhtml:link> child per version, itself included. Three versions mean three entries, each with the same three children. Declare the xhtml namespace on the <urlset>:

<?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/page/</loc>
    <xhtml:link rel="alternate" hreflang="en" href="https://example.com/en/page/"/>
    <xhtml:link rel="alternate" hreflang="de" href="https://example.de/page/"/>
    <xhtml:link rel="alternate" hreflang="de-CH" href="https://example.de/ch/page/"/>
  </url>
  <url>
    <loc>https://example.de/page/</loc>
    <!-- the same three xhtml:link lines -->
  </url>
  <url>
    <loc>https://example.de/ch/page/</loc>
    <!-- the same three xhtml:link lines -->
  </url>
</urlset>

Useful details from Google: the order of the children does not matter, and “Child elements don't count towards the URL limit for sitemaps.” The normal sitemap rules still apply, including that a sitemap can only contain URLs below the directory it is hosted in. In practice, a sitemap that lists URLs on other domains, as above, works when you have verified all of those domains in Search Console.

Which method to choose

For Google the methods are equivalent. You can use all three at once, but Google says “there's no benefit in Search”, and three implementations are much harder to keep in sync than one. The practical choice depends on your site:

Table · The three hreflang methods compared
HTML <link>HTTP Link headerXML sitemap
Where it livesIn the <head> of each pageIn the server response of each URLIn <xhtml:link> children of each <url>
Best forSmall and medium sites, CMS pluginsPDFs and other non-HTML filesLarge sites, many languages, separate systems per country
Visible on the pageYes, in the sourceOnly in response headersNo, only in the sitemap file
Page weightGrows with every language addedNone in the HTMLNone in the HTML
Main riskTags pushed into <body>, JavaScript changes, template driftForgotten in server config after changesSitemap goes stale when URLs change
How to checkView source and the rendered HTMLcurl -I or the browser's network panelParse the file, compare entries pair by pair
Google treats all three the same; choose the one your team can keep complete and correct.

What causes trouble is mixing methods by accident. A typical audit finding: a plugin prints HTML tags, someone later adds hreflang to the sitemap, and the two sets disagree on a URL or a code. If you switch methods, remove the old annotations, or make sure both produce exactly the same set.

x-default: the fallback page

“The reserved x-default value is used when no other language/region matches the user's browser setting.” It tells Google where to send searchers you have no version for, for example a Portuguese speaker on a site with only English and German pages.

Google adds: “While you can use the x-default value for any page, it was designed for language selector pages and so it will work best with those.” The value has no language code, because the page is meant for everyone not matched elsewhere. Google's example:

<link rel="alternate" href="https://example.com/en-gb" hreflang="en-GB" />
<link rel="alternate" href="https://example.com/en-us" hreflang="en-US" />
<link rel="alternate" href="https://example.com/en-au" hreflang="en-AU" />
<link rel="alternate" href="https://example.com/country-selector" hreflang="x-default" />

x-default is recommended, not required. If you have no selector page, it is common practice to use your main or international version, often the English one. The same URL can carry both a language code and x-default, for example hreflang="en" and hreflang="x-default" both pointing to https://example.com/en/. Like every other line, the x-default line belongs in the set on every version.

hreflang and canonical together

The two annotations answer different questions. The canonical says which URL represents a group of duplicates. hreflang says which URLs are alternates of each other. They work together only when each version is its own canonical.

Same-language regional versions

Pages for the US, UK and Australia in English are usually very similar. They are still valid alternates, and hreflang is exactly what lets Google show the right one. Give each version a self-referencing canonical, and make the differences real: currency, prices, spelling, delivery and contact details.

When you have true duplicates in the same language, Google's advice is different. If “both example.de/ and example.com/de/ show similar German language content”, you should “pick a preferred version and use the rel="canonical" element and hreflang tags to make sure that the correct language or regional URL is served to searchers.” The non-preferred URL canonicalises to the preferred one, and only the preferred one appears in the hreflang set.

hreflang also feeds canonical selection: “for canonicalization purposes Google prefers URLs that are part of hreflang clusters.” In Google's example, /de-de/cats and /de-ch/cats point to each other, /de-at/cats is left out, and the two linked pages are preferred as canonicals over the /de-at/ page.

URL structures for international sites

Each language or regional version needs its own URL. Google describes four ways to build them:

Table · URL structures, as Google describes them
StructureExampleProsCons
Country-specific domain (ccTLD)example.deClear geotargeting; server location irrelevant; easy separation of sitesExpensive, limited availability; more infrastructure; strict ccTLD requirements in some countries; targets a single country
Subdomain with gTLDde.example.comEasy to set up; allows different server locations; easy separation of sitesUsers might not recognise the targeting from the URL (is “de” the language or the country?)
Subdirectory with gTLDexample.com/de/Easy to set up; low maintenance on one hostUsers might not recognise the targeting from the URL; single server location; separation harder
URL parameterexample.com/?loc=deNot recommended by GoogleURL-based segmentation is difficult; users might not recognise the targeting
Every structure works with hreflang except that parameters are not recommended; the structure itself does not tell Google the audience.

Words in the URL do not set the target. Google says the subdomains en, en-gb, en-us and de in its example “are not used by Google to determine the target audience for the page; you must explicitly map the target audience.” Localised words and internationalised domain names are fine; use UTF-8 and escape the URLs properly in links.

To decide a page's target locale, Google uses ccTLDs, hreflang “whether in tags, headers, or sitemaps”, server location (not a definitive signal, because of CDNs) and other signals such as local addresses and phone numbers, local language and currency, links from local sites and a Business Profile. It ignores locational meta tags such as geo.position.

Not every two-letter domain counts as a country. Google treats .eu and .asia as generic, and also a list of ccTLDs that people use generically, including .ai, .co, .io, .me and .tv. A site on example.io is not targeted at the British Indian Ocean Territory; it needs hreflang to show which version is for whom.

Automatic redirects, IP detection and language switchers

Redirecting visitors by IP address or browser language looks helpful, but Google advises against it for two reasons.

Googlebot may never see your other versions. If you reroute users based on language settings, “Google might not find and crawl all your variations. This is because the Googlebot crawler usually originates from the USA. In addition, the crawler sends HTTP requests without setting Accept-Language in the request header.” A site that redirects every US visitor to /en-us/ may redirect Googlebot there too, every time.

Users get trapped. Google's guidance: “Avoid automatically redirecting users from one language version of a site to a different language version of a site.” “These redirections could prevent users (and search engines) from viewing all the versions of your site.” On IP detection specifically: “Don't use IP analysis to adapt your content. IP location analysis is difficult and generally not reliable.” Think of a German speaker in Spain, or a traveller on a hotel network.

What to do instead:

Check the URLs in your hreflang sets

OurSEO Tools crawls up to 1,000 pages and records the status code, canonical and indexability of every URL, so you can confirm that each language version returns 200, is indexable and is its own canonical.

69-point checklistTechnical crawlContent analysis

Common mistakes

How to audit hreflang step by step

  1. Crawl every version, all domains and folders, and export the hreflang set of each URL from HTML, headers and the sitemap.
  2. Check self-reference and completeness: each URL lists itself and the same set as its alternates.
  3. Check return links pair by pair: if A names B with a code, B names A.
  4. Validate every code against ISO 639-1 and ISO 3166-1 Alpha 2, and check for duplicate codes in one set.
  5. Check every target: absolute HTTPS URL, status 200, no redirect, no noindex, not blocked in robots.txt.
  6. Check canonical alignment: each target's canonical is itself and in the same language.
  7. Compare sources: if more than one method is in use, the sets must be identical; compare raw and rendered HTML on key templates too.
  8. Check the language of each page: one language for content and navigation, translated titles and descriptions, no side-by-side translations.
  9. Check redirects: request the localised URLs without cookies and without an Accept-Language header, as Googlebot does, and confirm none redirect.
  10. Check Search Console: use URL Inspection on samples to see that each version is indexed as its own canonical, and the Performance report filtered by country to see which version gets impressions where.

Google points to third-party hreflang generators and testing tools, with a caveat: they “are not maintained or checked by Google.” Search Console's old International Targeting report has been retired, so a crawl is now the main way to check a whole site.

FAQ

Does hreflang improve rankings?

No. It helps Google show the most suitable version of a page to each searcher. It does not make the pages rank higher, and it cannot make a version rank in a country where it would not rank on its own merits.

Is x-default required?

No, it is recommended. Use it for a language or country selector, or point it at your main international version. Without it, Google chooses the version itself for users you have no match for.

Do I need hreflang if my pages are in different languages anyway?

Google may find alternate language versions without it, but its advice is that “it is usually best for you to explicitly indicate your language- or region-specific pages.” For same-language regional versions, hreflang is the main way to tell Google which one is for whom.

Does Google use the lang attribute or the URL to detect language?

No. Google determines language from the visible content. Keep the lang attribute correct for browsers and accessibility, but it is not what Google uses.

Can I use HTML tags and a sitemap at the same time?

Yes, but there is no benefit in Search, and two sources are harder to keep identical. If they disagree, you are sending contradictory signals. Pick one.

Should the canonical of every language point to the main language?

No. Pages in different languages are not duplicates. Each version gets a self-referencing canonical, and hreflang connects them.

Sources

Quotes checked against the official pages on 30 October 2026.