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:
| Method | Where | Best For |
|---|---|---|
| HTML <link> tags | In the <head> of each page | Small sites with few language versions |
| HTTP headers | In the response headers | Non-HTML files (PDFs, etc.) |
| XML sitemaps | In your sitemap file | Most 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:
| Format | Meaning | Example |
|---|---|---|
| language | Any user of this language | en, es, fr, de, ja |
| language-region | Users of this language in this region | en-US, en-GB, es-MX, pt-BR |
| x-default | Fallback for unmatched users | x-default |
Common examples:
en-- English (any region)en-US-- English for the United Statesen-GB-- English for the United Kingdomes-- Spanish (any region)es-MX-- Spanish for Mexicozh-Hans-- Simplified Chinesezh-Hant-- Traditional Chinesex-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:
Validate the XML
Run your sitemap through a validator to catch syntax errors, missing namespaces, or malformed tags.
Check reciprocity
For every hreflang annotation, verify that the target page also references back. This is the most common failure point.
Monitor in Google Search Console
GSC's International Targeting report shows hreflang errors: missing return tags, unknown language codes, and non-indexable URLs.
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.
Related Articles
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.