Hreflang in Sitemaps: International SEO Guide

Implement hreflang in XML sitemaps for international SEO. Covers syntax, xhtml:link elements, x-default, common mistakes, and complete working examples.

If your site serves content in multiple languages or targets multiple regions, hreflang tells search engines which version to show to which audience. You can implement hreflang in HTML <link> tags, HTTP headers, or XML sitemaps. For most multi-language sites, the sitemap approach is the best option. Here's why, how the syntax works, the mistakes that will break your implementation, and a complete working example.

What Hreflang Does

Hreflang annotations tell search engines: "This page exists in multiple language/region versions. Here are all the versions and who each one is for."

When Google encounters a page with hreflang, it uses the annotations to:

  • Show the right version in search results based on the searcher's language and location
  • Avoid duplicate content issues -- Google understands that your English and Spanish pages aren't duplicates; they're translations
  • Consolidate ranking signals across language versions so they don't compete with each other

Without hreflang, Google guesses. It might show your English page to Spanish speakers, or your UK-targeted page to Australian users. It might treat your translated pages as duplicates and suppress some of them.

Three Ways to Implement Hreflang

You can declare hreflang annotations in three places:

MethodWhereBest For
HTML <link> tagsIn the <head> of each pageSmall sites with few language versions
HTTP headersIn the response headersNon-HTML files (PDFs, etc.)
XML sitemapsIn your sitemap fileMost sites, especially large ones

Why Sitemaps Are the Best Place for Hreflang

For most multi-language sites, implementing hreflang in your XML sitemap is the strongest approach. Here's why:

No page modification needed

You don't need to edit every page template or add tags to your HTML. The hreflang declarations live entirely in the sitemap, separate from your page code.

Scales to large sites

HTML <link> tags add significant overhead when you have 10+ language versions -- that's 10+ tags in the <head> of every page. Sitemaps handle this cleanly without bloating your HTML.

Easier to maintain

Updating hreflang in a sitemap means changing one file (or one generation script). Updating HTML tags means touching every page template and ensuring consistency across hundreds or thousands of pages.

Works for all URL types

HTML tags only work for HTML pages. Sitemaps work for any URL type -- HTML, PDF, images, or any other content.

Single source of truth

All your language mappings live in one place. Auditing and debugging is straightforward because you can see every annotation at once.

The main exception: if you have a very small site (under 10 pages) with only 2-3 language versions, inline HTML tags are simpler and work fine.

Hreflang Syntax in XML Sitemaps

The Namespace

Add the xhtml namespace to your <urlset> declaration:

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
        xmlns:xhtml="http://www.w3.org/1999/xhtml">

The Annotation Format

Inside each <url> entry, add xhtml:link elements for every language version of that page, including the page itself:

<url>
  <loc>https://example.com/about</loc>
  <xhtml:link rel="alternate" hreflang="en" href="https://example.com/about" />
  <xhtml:link rel="alternate" hreflang="es" href="https://example.com/es/about" />
  <xhtml:link rel="alternate" hreflang="fr" href="https://example.com/fr/about" />
</url>

Every xhtml:link element has three attributes:

  • rel="alternate" -- Always this value. Tells search engines these are alternate versions.
  • hreflang -- The language (and optionally region) code. Uses ISO 639-1 language codes and optionally ISO 3166-1 Alpha-2 region codes.
  • href -- The absolute URL of the alternate version.

Hreflang Value Format

The hreflang attribute value follows this pattern:

FormatMeaningExample
languageAny user of this languageen, es, fr, de, ja
language-regionUsers of this language in this regionen-US, en-GB, es-MX, pt-BR
x-defaultFallback for unmatched usersx-default

Common examples:

  • en -- English (any region)
  • en-US -- English for the United States
  • en-GB -- English for the United Kingdom
  • es -- Spanish (any region)
  • es-MX -- Spanish for Mexico
  • zh-Hans -- Simplified Chinese
  • zh-Hant -- Traditional Chinese
  • x-default -- Default/fallback version

Language codes are case-insensitive

Google treats en-US, en-us, and EN-US the same way. But for consistency and readability, use lowercase for the language and uppercase for the region: en-US, pt-BR, zh-TW.

The x-default Value

x-default is a special hreflang value that designates the fallback page -- the version shown to users whose language/region doesn't match any of your specific hreflang values. This is typically your language selector page, your default language version, or a universal landing page.

<xhtml:link rel="alternate" hreflang="x-default" href="https://example.com/about" />

You should always include x-default. Without it, Google has to guess which version to show to users who don't match any of your declared language/region combinations.

Validate your hreflang sitemap

Check for missing self-references, inconsistent mappings, and syntax errors in your hreflang annotations.

Complete Working Example

Here's a full sitemap for a site with English, Spanish, and French versions:

<?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">

  <!-- English homepage -->
  <url>
    <loc>https://example.com/</loc>
    <lastmod>2026-02-15</lastmod>
    <xhtml:link rel="alternate" hreflang="en" href="https://example.com/" />
    <xhtml:link rel="alternate" hreflang="es" href="https://example.com/es/" />
    <xhtml:link rel="alternate" hreflang="fr" href="https://example.com/fr/" />
    <xhtml:link rel="alternate" hreflang="x-default" href="https://example.com/" />
  </url>

  <!-- Spanish homepage -->
  <url>
    <loc>https://example.com/es/</loc>
    <lastmod>2026-02-15</lastmod>
    <xhtml:link rel="alternate" hreflang="en" href="https://example.com/" />
    <xhtml:link rel="alternate" hreflang="es" href="https://example.com/es/" />
    <xhtml:link rel="alternate" hreflang="fr" href="https://example.com/fr/" />
    <xhtml:link rel="alternate" hreflang="x-default" href="https://example.com/" />
  </url>

  <!-- French homepage -->
  <url>
    <loc>https://example.com/fr/</loc>
    <lastmod>2026-02-15</lastmod>
    <xhtml:link rel="alternate" hreflang="en" href="https://example.com/" />
    <xhtml:link rel="alternate" hreflang="es" href="https://example.com/es/" />
    <xhtml:link rel="alternate" hreflang="fr" href="https://example.com/fr/" />
    <xhtml:link rel="alternate" hreflang="x-default" href="https://example.com/" />
  </url>

  <!-- English pricing page -->
  <url>
    <loc>https://example.com/pricing</loc>
    <lastmod>2026-02-10</lastmod>
    <xhtml:link rel="alternate" hreflang="en" href="https://example.com/pricing" />
    <xhtml:link rel="alternate" hreflang="es" href="https://example.com/es/precios" />
    <xhtml:link rel="alternate" hreflang="fr" href="https://example.com/fr/tarifs" />
    <xhtml:link rel="alternate" hreflang="x-default" href="https://example.com/pricing" />
  </url>

  <!-- Spanish pricing page -->
  <url>
    <loc>https://example.com/es/precios</loc>
    <lastmod>2026-02-10</lastmod>
    <xhtml:link rel="alternate" hreflang="en" href="https://example.com/pricing" />
    <xhtml:link rel="alternate" hreflang="es" href="https://example.com/es/precios" />
    <xhtml:link rel="alternate" hreflang="fr" href="https://example.com/fr/tarifs" />
    <xhtml:link rel="alternate" hreflang="x-default" href="https://example.com/pricing" />
  </url>

  <!-- French pricing page -->
  <url>
    <loc>https://example.com/fr/tarifs</loc>
    <lastmod>2026-02-10</lastmod>
    <xhtml:link rel="alternate" hreflang="en" href="https://example.com/pricing" />
    <xhtml:link rel="alternate" hreflang="es" href="https://example.com/es/precios" />
    <xhtml:link rel="alternate" hreflang="fr" href="https://example.com/fr/tarifs" />
    <xhtml:link rel="alternate" hreflang="x-default" href="https://example.com/pricing" />
  </url>

</urlset>

Notice the pattern: every URL entry contains the full set of xhtml:link annotations pointing to all language versions, including itself. This is mandatory -- every page must reference every other version and itself.

Common Mistakes (and How to Avoid Them)

Hreflang implementations are notoriously error-prone. Here are the mistakes that break them:

1. Missing Self-Referencing Annotations

Every <url> entry must include an xhtml:link pointing to itself. If the English page lists Spanish and French alternates but doesn't list itself as the English alternate, Google may ignore the entire annotation set.

<!-- WRONG: missing self-reference -->
<url>
  <loc>https://example.com/about</loc>
  <xhtml:link rel="alternate" hreflang="es" href="https://example.com/es/about" />
  <xhtml:link rel="alternate" hreflang="fr" href="https://example.com/fr/about" />
</url>

<!-- CORRECT: includes self-reference -->
<url>
  <loc>https://example.com/about</loc>
  <xhtml:link rel="alternate" hreflang="en" href="https://example.com/about" />
  <xhtml:link rel="alternate" hreflang="es" href="https://example.com/es/about" />
  <xhtml:link rel="alternate" hreflang="fr" href="https://example.com/fr/about" />
</url>

2. Inconsistent Mappings (Non-Reciprocal Links)

Hreflang annotations must be reciprocal. If Page A says "my Spanish version is Page B," then Page B must say "my English version is Page A." If the mapping isn't bidirectional, Google ignores it.

This is the most common cause of hreflang failures on large sites, especially when different teams manage different language versions.

3. Wrong Language or Region Codes

Using incorrect codes silently breaks the annotation:

<!-- WRONG: 'uk' is the country code for Ukraine, not the language code for English UK -->
<xhtml:link rel="alternate" hreflang="uk" href="https://example.com/en-gb/" />

<!-- CORRECT: use en-GB for British English -->
<xhtml:link rel="alternate" hreflang="en-GB" href="https://example.com/en-gb/" />

Other common errors: jp instead of ja (Japanese), cn instead of zh (Chinese), br instead of pt-BR (Brazilian Portuguese).

4. Pointing to Non-Canonical URLs

Every href in your hreflang annotations must point to the canonical version of the page. If the URL redirects, is non-canonical, returns a 404, or has a noindex tag, Google ignores the annotation.

5. Incomplete Coverage

If you have 10 language versions but your sitemap only declares hreflang for 3 of them, the other 7 compete with each other as duplicates. Every language version must be declared in every URL entry.

6. Missing x-default

Without x-default, users whose language/region doesn't match any declared version get whichever version Google thinks is best -- which may not be the one you'd choose.

Audit regularly

Hreflang errors accumulate silently over time. New pages get added without annotations, URLs change without updating the sitemap, and language versions fall out of sync. Run a validation check monthly for any site with hreflang.

Regional Targeting Examples

Same Language, Different Regions

If you have separate pages for US English and UK English:

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

Here, en-US targets American users, en-GB targets British users, and plain en catches all other English speakers. The x-default catches everyone else.

Different Domains per Region

Some sites use country-specific domains:

<xhtml:link rel="alternate" hreflang="en-US" href="https://example.com/about" />
<xhtml:link rel="alternate" hreflang="de" href="https://example.de/ueber-uns" />
<xhtml:link rel="alternate" hreflang="fr" href="https://example.fr/a-propos" />
<xhtml:link rel="alternate" hreflang="x-default" href="https://example.com/about" />

Cross-domain hreflang works fine in sitemaps. Each domain's sitemap should contain the full set of annotations for its pages.

Scaling Hreflang with Sitemap Indexes

For large multilingual sites, the hreflang annotations can make your sitemap very large. Each URL entry contains N xhtml:link elements (one per language version), and you have N times as many URL entries (one per language version per page).

A site with 10,000 pages and 5 language versions means 50,000 URL entries, each with 5 xhtml:link elements. That's manageable with a sitemap index:

<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <sitemap>
    <loc>https://example.com/sitemap-en.xml</loc>
  </sitemap>
  <sitemap>
    <loc>https://example.com/sitemap-es.xml</loc>
  </sitemap>
  <sitemap>
    <loc>https://example.com/sitemap-fr.xml</loc>
  </sitemap>
</sitemapindex>

Each child sitemap handles one language version's URLs but still includes the full set of hreflang annotations for all language versions.

Verifying Your Implementation

After deploying hreflang in your sitemap, verify it works:

1

Validate the XML

Run your sitemap through a validator to catch syntax errors, missing namespaces, or malformed tags.

2

Check reciprocity

For every hreflang annotation, verify that the target page also references back. This is the most common failure point.

3

Monitor in Google Search Console

GSC's International Targeting report shows hreflang errors: missing return tags, unknown language codes, and non-indexable URLs.

4

Test with live search results

Search for your content from different regions (using Google's country-specific domains or VPN) and verify the correct language version appears.

Hreflang in sitemaps is the most scalable and maintainable approach to international SEO. The syntax is straightforward, but the devil is in the details -- self-references, reciprocity, and correct language codes. Get those right, and your multilingual site will serve the right content to the right audience.


Hreflang is fiddly. Sitemaps make it manageable. Get the self-references and reciprocity right, and you're 90% of the way there.

Validate your XML sitemap

Check your sitemap for errors, broken URLs, and indexing issues. Free instant validation.