hreflang implementation: head, sitemap or header, and the checks

You add hreflang in one of three places: the head, the sitemap, or the HTTP header. This guide shows each with a worked example, the rules you cannot break, the checks to run, and the traps that waste weeks.

By , founder of Porteur · Updated 14 September 2026 · Markdown

Pick your site structure before hreflang

Decide where each language or country version will live. This choice sets your URLs and how you maintain them.

  • ccTLD: example.fr. Strongest geographic signal, counts as a separate site. More setup and link building per country.
  • Subdirectory: example.com/fr/. One host and one link profile. Easier operations.
  • Subdomain: fr.example.com. Usually treated as part of the site, can be seen as separate.
  • URL parameter: example.com/?lang=fr. Discouraged.

Google says all three, apart from parameters, work. Choose based on your operations and how you earn links. Keep to one pattern across the site.

The three hreflang implementation methods

Use only one method per page set. All pages in a language set must list all alternates, including themselves. Here are examples for /pricing in English and French, plus a catch-all.

1) Link elements in the head

<link rel="alternate" hreflang="en" href="https://example.com/pricing" />
<link rel="alternate" hreflang="fr" href="https://example.com/fr/prix" />
<link rel="alternate" hreflang="x-default" href="https://example.com/pricing" />

Add the same three tags on both URLs. Each page lists itself and the other versions. Use absolute URLs. Place tags in the HTML head.

2) Hreflang in the XML sitemap

<?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/pricing</loc>
    <xhtml:link rel="alternate" hreflang="en" href="https://example.com/pricing" />
    <xhtml:link rel="alternate" hreflang="fr" href="https://example.com/fr/prix" />
    <xhtml:link rel="alternate" hreflang="x-default" href="https://example.com/pricing" />
  </url>
  <url>
    <loc>https://example.com/fr/prix</loc>
    <xhtml:link rel="alternate" hreflang="en" href="https://example.com/pricing" />
    <xhtml:link rel="alternate" hreflang="fr" href="https://example.com/fr/prix" />
    <xhtml:link rel="alternate" hreflang="x-default" href="https://example.com/pricing" />
  </url>
</urlset>

Put all alternates inside each <url> block. Submit the sitemap in Search Console after you deploy it. Keep it updated when you add pages.

3) HTTP header for non-HTML files

Link: <https://example.com/pricing>; rel="alternate"; hreflang="en",
      <https://example.com/fr/prix>; rel="alternate"; hreflang="fr",
      <https://example.com/pricing>; rel="alternate"; hreflang="x-default"

Use headers for files like PDFs where you cannot edit the HTML. For HTML pages, the head or the sitemap is simpler to debug at scale.

The hreflang rules you cannot break

  • Reciprocal: if /fr/prix points to /pricing, /pricing must point to /fr/prix.
  • Self referencing: each page lists itself as one of the alternates.
  • ISO codes: use language codes like en, fr. For region, add a hyphen and ISO country code, like en-GB, fr-CA.
  • x-default: point this to a neutral or selector page when you have one. If not, it can point to your main language page.
  • Canonicals: keep canonicals within each language. Do not canonical English to French or vice versa.
  • Only indexable URLs: point hreflang at live 200 pages, not 3xx, 4xx, or noindex pages.
  • One language per URL: do not mix language content on a page. Do not auto-translate on the fly for the same URL.
<!-- Correct: English UK and English US are separate when content differs -->
<link rel="alternate" hreflang="en-GB" href="https://example.com/uk/pricing" />
<link rel="alternate" hreflang="en-US" href="https://example.com/us/pricing" />

<!-- Wrong: en-UK is not a valid code; use en-GB -->
<link rel="alternate" hreflang="en-UK" href="https://example.com/uk/pricing" />

A fixed page pair has the same subject and structure, written for each locale. Example: /guides/getting-started and /fr/guides/demarrer use the same steps, not mixed languages, with localised dates and currency.

Worked examples for a small product site

Say you have example.com in English and a French section under /fr/. You want hreflang on /pricing and /fr/prix, plus the home pages. Here is the minimum set.

<!-- /pricing head -->
<link rel="alternate" hreflang="en" href="https://example.com/pricing" />
<link rel="alternate" hreflang="fr" href="https://example.com/fr/prix" />
<link rel="alternate" hreflang="x-default" href="https://example.com/" />

<!-- /fr/prix head -->
<link rel="alternate" hreflang="en" href="https://example.com/pricing" />
<link rel="alternate" hreflang="fr" href="https://example.com/fr/prix" />
<link rel="alternate" hreflang="x-default" href="https://example.com/" />

<!-- Home pages head -->
<!-- / -->
<link rel="alternate" hreflang="en" href="https://example.com/" />
<link rel="alternate" hreflang="fr" href="https://example.com/fr/" />
<link rel="alternate" hreflang="x-default" href="https://example.com/" />

<!-- /fr/ -->
<link rel="alternate" hreflang="en" href="https://example.com/" />
<link rel="alternate" hreflang="fr" href="https://example.com/fr/" />
<link rel="alternate" hreflang="x-default" href="https://example.com/" />

If you prefer sitemap implementation, mirror the same mapping there. Keep x-default pointing to a neutral page that helps users choose when you have one, for example /language or the home page with a clear switch.

Avoid these hreflang errors

  • Non-reciprocal sets: /fr/prix links to /pricing, but /pricing does not link back. Fix by adding the return link.
  • Pointing at non-canonical URLs: you list /pricing?ref=ad. Use the clean canonical URL in hreflang.
  • Wrong codes: en-UK, zh-cn in lower case, or using country with no language. Use en-GB, zh-CN, and always include the language.
  • Broken or redirected targets: 404 or 301. Point to live 200 pages only.
  • Noindex targets: the alternate is blocked. Remove noindex or remove it from the hreflang set.
  • Cross-language canonicals: /fr/prix canonicalises to /pricing. Each language should self-canonicalise.
  • Mixed-method conflicts: head says one set, sitemap another. Use one method per page set.
  • Missing self references: every page must include itself in the set.
  • Alternate points to the wrong page: French points to an English category, not the French equivalent. Map one to one.

If you see traffic to the wrong language from a country, check wrong region codes first. For example en-AU versus en-GB for a UK audience. Then check for missing return links and redirects in the chain.

Checks: your own crawl and Search Console

You can check hreflang in two passes. First with your own crawl or script to find gaps. Then in Search Console to confirm Google sees the mapping.

  1. Make a URL map

    Export a list of language pairs. For example, /pricing ↔ /fr/prix, /guides/getting-started ↔ /fr/guides/demarrer. Put it in a sheet.

  2. Check the head or sitemap

    If you use head tags, sample ten pairs and view source. If you use a sitemap, open it and search for the pair. Confirm self-references and reciprocity.

  3. Look for non-200 targets

    Fetch the URLs. Fix any that are redirected, blocked or 404. Hreflang should point only to final 200 pages.

  4. Verify codes

    Scan for invalid tags like en-UK, en_GB, or zh-cn. Use language in lower case, region in upper case, with a hyphen, for example fr-CA.

  5. Use Search Console

    Inspect each URL in the URL Inspection tool. Check the hreflang section for detected alternates and whether Google can fetch them. Submit sitemaps and watch indexing.

Search Console no longer has the International Targeting report. There is no geo-targeting setting for gTLDs as of 2026. Use the URL Inspection tool and the Sitemaps report instead. The Sitemaps report confirms Google fetched your sitemap and discovered URLs. The Inspection tool shows what Google found on a given URL, including hreflang annotations it detected for that URL.

After changes, request indexing for a small set of pages. Monitor impressions per language in the Performance report. A fixed page shows the right version rising in the target country for queries like “prix yourproduct”.

When to add a language and how to translate

Add a language when you already see impressions from that country in Search Console, you sell there, and your support can answer in it. A second language is a second site to maintain.

  • Translate for what people search, not word for word. Use native queries in titles, descriptions and headings.
  • Translate the slug, alt text and structured data too.
  • Localise currency, units, dates and examples.
  • Have a human review machine translations. Google’s spam policies list content translated automatically without human review as scaled content abuse.
  • Keep one language per URL. Do not swap languages on the same URL based on headers or scripts.

A fixed page pair looks like this: /features uses “Feature A”, /fr/fonctionnalites uses “Fonction A”. The images have matching alt text in each language. The schema markup carries translated names and descriptions.

What hreflang does and does not do

  • Hreflang tells Google which language or region version of a page to show to a searcher.
  • It helps reduce wrong-language impressions and cannibalisation across languages.
  • It does not merge ranking signals across languages. Each URL earns on its own.
  • It does not fix thin content. Each page still needs value of its own.
  • It does not override canonicals or redirects. Fix those first.

Use hreflang after you have real translations and clean duplicates. Then check your Performance report by country and query. You should see the right URLs show for queries like “tarifs yourproduct” in France and “pricing yourproduct” in the UK.

ccTLD, subdirectory or subdomain for international SEO

As of 2026, a ccTLD is the strongest geographic signal and is a separate site. A subdirectory keeps one host and one link profile. A subdomain is usually treated as part of the site but can be seen as separate. Google supports all three. Choose based on operations and how you build links. Avoid URL parameters for language.

StructureExampleProsConsChoose when
ccTLDexample.frStrong country signal, clear to usersSeparate site to run, links do not flow by defaultYou run teams and campaigns per country
Subdirectoryexample.com/fr/One site to crawl, share links, simpler opsWeaker country cue to usersYou want one codebase and shared authority
Subdomainfr.example.comFlexible routing, can separate appsCan be seen as separate, split opsYou need routing separation but want same root domain

Questions

Sources

Check my site, free

Paste your URL to see which pages should get hreflang next and which errors block them, in about thirty seconds, free, with three findings shown whole.

  • Free check, no card
  • Read-only, your own accounts
  • Readable by your agent

Read next