Website Spec
Internationalisation Optional Updated 2026-05-29

hreflang in XML sitemaps

Declare language and regional alternates inside the XML sitemap with xhtml:link instead of in the HTML head. Easier to maintain at scale and keeps localisation metadata separate from content.

What it is

The sitemap form of hreflang. Instead of declaring language and regional alternates with <link rel="alternate" hreflang="..."> in every HTML head, you list them once per URL inside the XML sitemap using the <xhtml:link> element. The namespace xmlns:xhtml="http://www.w3.org/1999/xhtml" is declared on the root <urlset>. The signal sent to search engines is identical to the inline form — only the delivery mechanism changes.

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
        xmlns:xhtml="http://www.w3.org/1999/xhtml">
  <url>
    <loc>https://example.com/en/page</loc>
    <xhtml:link rel="alternate" hreflang="en" href="https://example.com/en/page"/>
    <xhtml:link rel="alternate" hreflang="de" href="https://example.com/de/seite"/>
    <xhtml:link rel="alternate" hreflang="fr" href="https://example.com/fr/page"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://example.com/en/page"/>
  </url>
  <url>
    <loc>https://example.com/de/seite</loc>
    <xhtml:link rel="alternate" hreflang="en" href="https://example.com/en/page"/>
    <xhtml:link rel="alternate" hreflang="de" href="https://example.com/de/seite"/>
    <xhtml:link rel="alternate" hreflang="fr" href="https://example.com/fr/page"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://example.com/en/page"/>
  </url>
  <url>
    <loc>https://example.com/fr/page</loc>
    <xhtml:link rel="alternate" hreflang="en" href="https://example.com/en/page"/>
    <xhtml:link rel="alternate" hreflang="de" href="https://example.com/de/seite"/>
    <xhtml:link rel="alternate" hreflang="fr" href="https://example.com/fr/page"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://example.com/en/page"/>
  </url>
</urlset>

Why it matters

On a large multilingual site, declaring hreflang inline becomes painful. A cluster of ten locales means ten <link> elements in every page’s head, every locale, every template — eleven with x-default. Adding an eleventh locale touches every template and every cached page. Moving the declaration to the sitemap keeps page HTML clean, centralises localisation metadata in one machine-generated file, and lets you add or remove a locale by regenerating one document.

The signal is equivalent. Google, Bing and Yandex all read <xhtml:link> entries from the sitemap as authoritative alternates.

How to implement

  • Pick one delivery method per site. Use either inline hreflang in the HTML head, the HTTP Link header, or sitemap <xhtml:link> — not several at once on the same URLs. Mixed signals get ignored or produce conflicts.
  • Declare the namespace. Add xmlns:xhtml="http://www.w3.org/1999/xhtml" on the root <urlset>.
  • Group all alternates inside each <url>. Every <url> entry lists every alternate URL in the group, including itself. The bidirectional rule still applies: if A lists B, B must list A.
  • Self-reference always. Each URL must include a <xhtml:link> pointing at itself with its own hreflang. Omitting it invalidates the entire cluster.
  • Add x-default. Point it at the language selector or the default-region landing page.
  • Use BCP 47 tags. Language (en, de), or language plus region (en-GB, pt-BR). Never a country code on its own.
  • Reach for the sitemap when you have many locales, many pages, or generate alternates from the same source that already generates the sitemap. Reach for inline <link> when you don’t ship an XML sitemap, or when alternates differ from how the sitemap is built.

Common mistakes

  • Forgetting the xmlns:xhtml namespace declaration — the entries parse but search engines ignore them.
  • Listing only the “other” languages and skipping the self-reference.
  • Shipping both inline <link rel="alternate"> and sitemap <xhtml:link> for the same URLs, with different sets.
  • Pointing alternates at non-canonical URLs, redirects, or 404s.
  • Splitting a language cluster across multiple sitemap files — keep all alternates of a URL inside the same <url> entry.

Verification

  • Fetch the sitemap and confirm the xhtml namespace is declared on <urlset>.
  • Pick one URL and confirm every alternate listed there reciprocally lists it back.
  • Use Search Console’s International Targeting report (or equivalent) to confirm clusters are detected without “no return tags” errors.

Related topics

Sources & further reading

Search
esc close navigate open