# 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.

Updated 2026-09-14 · Source: https://porteur.ai/guides/hreflang-implementation

## 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.

> One language per URL. Do not mix languages on the same page.

## 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

```html
<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
<?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

```http
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.

> Pick one implementation method and stick to it for a page set. Do not mix head and sitemap hreflang for the same URLs.

## 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.

```html
<!-- 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.

> Do not redirect by IP or browser language. Googlebot crawls from the US and would never see other versions. Use a visible language switch with real links.

## 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.

```html
<!-- /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.

> Keep your alternate links and canonicals in sync. Canonicals decide the duplicate cluster. Hreflang swaps the language choice inside that cluster, it does not override canonicals.

## 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”.

## Language switching, internal links and sitemaps

Do not hide languages behind scripts. Give each language a visible switch with a real link to the mapped URL. For example, /pricing links to /fr/prix with an anchor tag, not a script click handler.

- Translate internal links. A French page links to French pages, not English.
- Keep a sitemap per language, or one sitemap with hreflang entries.
- Use consistent slugs per language. Translate them. For example, /guides/getting-started becomes /fr/guides/demarrer.
- Localise currency, dates and examples on the page.
- Set the HTML lang attribute correctly, for example <html lang="fr"> on French pages. This is separate from hreflang and helps browsers and assistive tech.

> Never redirect users by IP or browser language. Show a prompt with links instead. Googlebot would miss your alternates otherwise.

## 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.

| Structure | Example | Pros | Cons | Choose when |
| --- | --- | --- | --- | --- |
| ccTLD | example.fr | Strong country signal, clear to users | Separate site to run, links do not flow by default | You run teams and campaigns per country |
| Subdirectory | example.com/fr/ | One site to crawl, share links, simpler ops | Weaker country cue to users | You want one codebase and shared authority |
| Subdomain | fr.example.com | Flexible routing, can separate apps | Can be seen as separate, split ops | You need routing separation but want same root domain |

## Questions

### How do I implement hreflang the simplest way?

Use the sitemap method if you have many pages. It keeps all mappings in one place and is easier to audit. For a few pages, head tags are fine. Pick one method and apply it to every page in the set.

### What is hreflang used for?

It tells Google which language or region version of a page to show. It reduces wrong-language results. It does not boost rankings by itself or combine link signals across languages.

### Do I need x-default?

Use x-default when you have a neutral page like a language chooser or a global page. If you do not have one, point x-default to your main language. Keep it consistent across the set.

### How do I fix hreflang errors?

Start with reciprocity and self references. Then check codes, canonicals and target status codes. Remove non-canonical, redirected or noindex URLs from the set. Use URL Inspection in Search Console to confirm what Google sees.

### How do you pronounce hreflang?

Say h-ref-lang. The h comes from the HTML attribute name href, and lang is for language.

### Should I use en-UK or en-GB?

Use en-GB. The region code is the ISO country code in upper case. For the United States use en-US. Avoid made-up codes like en-EU.

## Read next

- [International SEO for a small product: structure, language, and when to start](https://porteur.ai/guides/international-seo): Pick a structure, set one language per URL, add hreflang, and know when to expand. A short plan for founders shipping their own product site.
- [Multilingual website SEO: one language per URL, and everything translated](https://porteur.ai/guides/multilingual-website-seo): Set up a multilingual website that ranks: one language per URL, fully translated content, hreflang, a real switcher, and a sitemap for each language.
- [Subdomain vs subdirectory: what Google says and what to choose](https://porteur.ai/guides/subdomain-vs-subdirectory): Google says both can work. Here is how to choose for blogs, docs, languages and new products, and how to move with clean redirects.
- [hreflang](https://porteur.ai/glossary/hreflang): hreflang tells search engines the language and region for each page version. See when you need it, where to declare it, and how to avoid errors.
- [The Sitemaps report: what Success, Has errors and Couldn’t fetch mean](https://porteur.ai/guides/search-console-sitemaps-report): How to submit your sitemap URL, read Success, Has errors and Couldn’t fetch, and fix invalid XML, 404s, cross‑host URLs and missing child sitemaps.
- [How to use the URL Inspection tool in Search Console](https://porteur.ai/guides/url-inspection-tool): Read each panel, run Test live URL, and know when to request indexing. Fix new pages, dropped pages, and canonicals Google ignores.
- [Sitemap index](https://porteur.ai/glossary/sitemap-index): A sitemap index lists your sitemap files. Use it when you split URLs by section or language, or pass one sitemap’s 50,000 URL or 50 MB limit.
- [Nuxt SEO: useSeoMeta, the SEO modules, and the client-rendering trap](https://porteur.ai/guides/nuxt-seo): Ship Nuxt pages that Google can crawl: server-rendered HTML, correct meta, a clean sitemap and robots, schema, fast images, and no client-only content.

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: https://porteur.ai/
