ArticleMultilingual SEO

Hreflang in XML sitemaps: syntax, limits and common errors

When to put hreflang in a sitemap instead of the page head, one valid multilingual sitemap to copy, Google's size limits and the errors that break the file.

Published
Reading time
7 min read
Two skaters glide toward each other across a frozen lake at dusk, past a sauna cabin whose door carries leaf tiles.
On this page
  1. Head, sitemap or HTTP header: which one fits?
  2. A valid multilingual sitemap
  3. The rules, from Google's documentation
  4. How big can a multilingual sitemap get?
  5. Should lastmod change when a translation is published?
  6. Common errors
  7. How do you check a hreflang sitemap?
  8. Multilingual sitemaps on WordPress
  9. Where LangRelay puts the set

An XML sitemap can carry the whole hreflang set, so the pages themselves don't have to. Declare the xhtml namespace on the <urlset> element, give every language version its own <url> entry, and inside each entry add one <xhtml:link rel="alternate"> for every version, that entry's own URL included. Google calls the sitemap, head tags and HTTP headers "equivalent", so use the sitemap when it is the place your stack can keep correct, and use one method rather than two.

Head, sitemap or HTTP header: which one fits?#

Google accepts the same set in three places. Its documentation says you can use all three at once but that "there's no benefit in Search", and that three implementations are harder to manage than one. What decides it is where your site can generate the list reliably.

Method

Where the set lives

Fits when

Watch out for

Link tags in the <head>

In every HTML page

Templates print the page, and each page knows its translations

The set adds a few lines to every page and has to be right on every one

XML sitemap

In one or more sitemap files

Templates are hard to change, the site is large, or a separate system knows the translations

Nobody sees the set by viewing a page, and the file has to change whenever a translation goes live or is withdrawn

HTTP Link header

In the response headers

Files with no <head>, such as PDFs

Server or CDN configuration per URL

Yoast's hreflang guide makes the case for the sitemap from the operator's side. The markup adds no weight to pages that visitors download, and it is usually easier to change one sitemap than every page of a site, which can spare a long approval process. Its complaint is the size: the sitemap form is "very verbose". The reason is visible in the sample below: every URL repeats the full list.

If you do run two methods, for example during a migration from head tags to a sitemap, make sure they say the same thing. Two sources that disagree about which URL is the Portuguese version leave you guessing which one Google used.

A valid multilingual sitemap#

An outdoor shop publishes its tents page in English, with Spanish and Portuguese translations under /es/ and /pt/. English is also the fallback for everyone else. This sitemap describes that one page in all three languages:

<?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://www.alderbrook.example/tents/</loc>
    <lastmod>2026-09-30</lastmod>
    <xhtml:link rel="alternate" hreflang="en" href="https://www.alderbrook.example/tents/"/>
    <xhtml:link rel="alternate" hreflang="es" href="https://www.alderbrook.example/es/tents/"/>
    <xhtml:link rel="alternate" hreflang="pt" href="https://www.alderbrook.example/pt/tents/"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://www.alderbrook.example/tents/"/>
  </url>
  <url>
    <loc>https://www.alderbrook.example/es/tents/</loc>
    <lastmod>2026-10-02</lastmod>
    <xhtml:link rel="alternate" hreflang="en" href="https://www.alderbrook.example/tents/"/>
    <xhtml:link rel="alternate" hreflang="es" href="https://www.alderbrook.example/es/tents/"/>
    <xhtml:link rel="alternate" hreflang="pt" href="https://www.alderbrook.example/pt/tents/"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://www.alderbrook.example/tents/"/>
  </url>
  <url>
    <loc>https://www.alderbrook.example/pt/tents/</loc>
    <lastmod>2026-10-04</lastmod>
    <xhtml:link rel="alternate" hreflang="en" href="https://www.alderbrook.example/tents/"/>
    <xhtml:link rel="alternate" hreflang="es" href="https://www.alderbrook.example/es/tents/"/>
    <xhtml:link rel="alternate" hreflang="pt" href="https://www.alderbrook.example/pt/tents/"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://www.alderbrook.example/tents/"/>
  </url>
</urlset>

The second namespace declaration, xmlns:xhtml, is what makes the xhtml: prefix legal. Without it the file is not well-formed XML once namespaces are taken into account, and a strict parser stops at the first <xhtml:link>.

Each translation has an entry of its own. A sitemap that lists only the English URL in <loc> and tucks the Spanish and Portuguese URLs inside it as alternates is missing two thirds of the set. Google's rules ask for a separate <url> element for each URL, and its return-link rule needs the Spanish entry to point back at the English one.

The <lastmod> dates differ. The Portuguese page went live on 4 October, two days after the Spanish one, so its date is its own.

The rules, from Google's documentation#

Google's page on localized versions, last updated on 2026-09-21, lists the sitemap rules, and its general hreflang guidelines apply on top:

  1. Declare xmlns:xhtml="http://www.w3.org/1999/xhtml".
  2. Create a separate <url> element for each URL, with a <loc> child naming that page.
  3. Give each <url> an <xhtml:link rel="alternate" hreflang="..."> child for every alternate version, including itself. The article on self-referencing hreflang and x-default explains why the entry's own line matters.
  4. Use fully qualified URLs with the scheme, so https://example.com/foo and never /foo or //example.com/foo. This holds for <loc> as well: Google's sitemap guide says it "will attempt to crawl your URLs exactly as listed".
  5. Alternate URLs may sit on other domains, which matters if your languages live on subdomains or country domains (see subdomain vs subdirectory). If two pages don't point to each other, though, Google ignores the tags.
  6. Everything else in Google's sitemap documentation applies to the extension too: UTF-8 encoding, entity-escaped values and the size limits below.

The language codes are the same as in head tags: an ISO 639-1 language, optionally followed by an ISO 3166-1 Alpha 2 region, or x-default.

How big can a multilingual sitemap get?#

Google limits a single sitemap to 50 MB uncompressed or 50,000 URLs. Past either limit you split the file and list the parts in a sitemap index, which can itself hold up to 50,000 sitemaps. Search Console accepts up to 500 sitemap index files per site.

Hreflang makes a sitemap grow faster than the page count suggests. Each language version is its own <url> entry, and each entry repeats the full list. A site with 3,000 pages in one original and four translations has 15,000 entries, each carrying six <xhtml:link> lines (five languages and x-default), so 90,000 link lines in total. That stays under the URL limit, but each link line in the sample above is about 100 characters, so at that length the alternates alone come to about 9 MB. Plan the split before the file reaches the limit, for example one sitemap per section, with every language of a section in the same file so each set can be read in one place.

Should lastmod change when a translation is published?#

Yes, for the translated URL. Google uses <lastmod> only when it is "consistently and verifiably" accurate, and it describes a significant update as a change to the main content, the structured data or the links on the page. A new or revised translation is exactly that for the translated URL. It is not a change to the original, so leave the original's date alone, even though its alternate list grew by one line.

Common errors#

Error

What you see

Fix

xmlns:xhtml missing

The file fails to parse at the first <xhtml:link>

Declare both namespaces on <urlset>

Wrong sitemap namespace (for example .../sitemap/.9)

Search Console reports an incorrect namespace or unsupported format

Use http://www.sitemaps.org/schemas/sitemap/0.9 exactly

Only the original has a <url> entry

Return links are missing for every translation

Give every version its own entry with the full list

An entry lacks its own line

The set on that entry is incomplete

Generate the list once and print it in every entry

Relative href or <loc> values

Google cannot use them

Write full https:// URLs

A raw & in a URL with a query string

A parsing error

Escape it as &amp;

Curly quotes around attribute values

An unsupported format error

Use straight quotes; word processors insert curly ones

Sitemap on www lists URLs without it, or the reverse

A path mismatch error

Keep the host consistent with the sitemap's location

Alternates that redirect, return 404 or carry noindex

Those versions cannot be shown

List only final, indexable URLs

Google's sitemap guide also asks you to include the URLs you want in its results, which in practice means the canonical URL of each version. A translated page whose canonical points at the original should not be in the sitemap as a translation; the article on hreflang and canonical tags covers that conflict.

How do you check a hreflang sitemap?#

Start with the file itself:

curl -s https://www.alderbrook.example/sitemap.xml | xmllint --noout -
curl -s https://www.alderbrook.example/sitemap.xml | grep -c '<url>'

The first command prints nothing when the XML parses. The second counts entries, which should equal your page count times the number of languages that are live for each page.

Then submit the sitemap, or the index, in Search Console's Sitemaps report. The report shows only sitemaps submitted there or through the API, not ones Google found through robots.txt, so submit it even if your robots.txt already has a Sitemap: line. A status of Success means the file was read without errors. Has errors means the file was fetched but some entries failed, and only the entries that parsed cleanly are queued for crawling. Discovered pages counts the URLs it found, and Google adds that a discovered URL is no guarantee of crawling or indexing. To check a single translated URL afterwards, use URL Inspection on it.

Multilingual sitemaps on WordPress#

WordPress has generated a basic XML sitemap since version 5.5, built from providers for posts, taxonomies and users that plugins can extend or replace. Most multilingual WordPress sites use the sitemap of an SEO plugin instead, and the translation plugin adds the hreflang to it:

  • WPML's documentation says it prints <xhtml:link rel="alternate"> entries inside the XML sitemaps of Yoast SEO and Rank Math, and tells you to look for them under /sitemap.xml for Yoast SEO or /sitemap_index.xml for Rank Math.
  • Rank Math's knowledge base says translated posts appear in its sitemap index automatically and that WPML adds the hreflang to the translated pages.
  • TranslatePress's SEO Pack documentation says the add-on extends the sitemaps of SEO plugins and creates a multilingual sitemap automatically. The SEO Pack is available only in the premium versions (Personal, Business or Developer), so the free plugin does not do this.

In each case the translated URLs reach the SEO plugin's sitemap through the translation plugin's integration with it. Hreflang in WordPress covers how to see which plugin printed which tags.

Where LangRelay puts the set#

LangRelay's WordPress plugin prints the hreflang set as link tags in the <head> of the original page and of each translated version. It adds nothing to your sitemaps and does not generate a sitemap of its own, so your SEO plugin's sitemap keeps listing your original URLs as it does today.

The translated pages are not separate WordPress posts. The plugin serves /es/tents/ from the original post and translates the rendered page, so a crawler reaches the Spanish URL through the set in the original's head, through the language switcher's links and through internal links, which the plugin points at the same language on a translated page. The set in the head is enough for Google to connect the versions: its documentation treats the three methods as equivalent. A language appears in it once that page's translation is live.

Our hreflang guide has the rest of the rules for the set, and hreflang vs the HTML lang attribute covers the attribute the head needs as well. For the feature overview see multilingual SEO, and to look at the plugin's output on your own site, book a demo.

Sources

The pages this one cites, with the day each was read.

  1. 01Localized versions of your pages (Google Search Central, last updated 2026-09-21)developers.google.com, checked 6 October 2026
  2. 02Build and submit a sitemap (Google Search Central, last updated 2026-07-08)developers.google.com, checked 6 October 2026
  3. 03Manage your sitemaps with a sitemap index file (Google Search Central, last updated 2025-12-10)developers.google.com, checked 6 October 2026
  4. 04Manage your sitemaps using the Sitemaps report (Search Console Help)support.google.com, checked 6 October 2026
  5. 05Sitemaps XML format (sitemaps.org)sitemaps.org, checked 6 October 2026
  6. 06hreflang: the ultimate guide (Yoast, published 2022-03-01, modified 2024-08-21)yoast.com, checked 6 October 2026
  7. 07How to Translate Your Site for Multilingual SEO (WPML documentation, last updated 2026-07-02)wpml.org, checked 6 October 2026
  8. 08Multilingual SEO with Rank Math SEO and WPML (Rank Math knowledge base)rankmath.com, checked 6 October 2026
  9. 09Multilingual SEO (TranslatePress)translatepress.com, checked 6 October 2026
  10. 10SEO Pack (TranslatePress documentation)translatepress.com, checked 6 October 2026
  11. 11New XML Sitemaps Functionality in WordPress 5.5 (Make WordPress Core, 2020-07-22)make.wordpress.org, checked 6 October 2026
  • hreflang
  • multilingual SEO
  • XML sitemap
Part of a guide

Book a demo

See LangRelay on your own site

Book 30 minutes with the team. We translate one of your pages live and walk through review, publishing and multilingual SEO.