To declare language versions in an XML sitemap, give every page its own url entry with a loc value, and inside that entry add one xhtml:link element for every version of the page, itself included, each with rel="alternate", an hreflang value and a fully qualified href. Google treats the sitemap, the HTML link tags and the HTTP header as equivalent ways to say the same thing, so the sitemap is a choice about where you can maintain the information reliably, not a way to rank better.
This is aimed at exporters, store teams and agencies who run several language versions and want one file, rather than thousands of templates, to carry the relationship. Mistakes in the tags themselves are covered in the hreflang audit checklist; the focus here is writing the sitemap, splitting it, and proving it is correct before you submit it.
Choosing among the three methods
Google's localized-versions documentation lists three ways to tell Search about alternate language and region pages: link elements in the HTML head, an HTTP Link header, and an XML sitemap. It states that the three are equivalent from Google's perspective. It also says that using all three brings no benefit in Search and makes management harder than picking one (Google: Localized versions of your pages (Opens in a new tab)).
The page gives a use case for two of the methods. HTML tags suit sites that have no sitemap or cannot set HTTP response headers. The HTTP header is shown for non-HTML files, with a PDF as the example. For the sitemap method it lists the rules but no advantages or drawbacks. Whatever reasons you have for choosing it are therefore practical suggestion.
| Situation | Why the sitemap helps | What to weigh |
|---|---|---|
| Templates are hard to change | The relationship lives in one file outside the page code | You must keep the file in sync with published pages |
| Many pages and many languages | Page heads stay light | File size grows with the number of versions |
| Versions already listed in a data source | The same list generates the sitemap | The generator needs to be tested |
| Non-HTML files need alternates | A url entry can describe them | The HTTP header is the method the documentation illustrates for these files |
| No sitemap exists and none is planned | Not suitable | HTML link tags work |
Pick one method and keep to it. If the sitemap and the page head both carry the relationship, they can drift apart over time and you have two sources to audit instead of one.
Anatomy of a sitemap entry
The documentation for the sitemap method is short. The root element declares the xhtml namespace, xmlns:xhtml="http://www.w3.org/1999/xhtml". Each URL gets its own url element with a loc child. Inside that url element go the xhtml:link elements, one per version, including a link to the page itself. The order of the elements does not matter. A sitemap can only contain URLs that are descendants of the directory it is hosted in, and the general sitemap guidelines apply.
| Piece | Value | What the documentation says |
|---|---|---|
| Namespace | xmlns:xhtml set to the xhtml namespace address | Declared on the root element |
| url | One element per page address | Each page has its own url element |
| loc | The page's full address | Fully qualified, protocol included |
| xhtml:link rel | alternate | One link element per version |
| xhtml:link hreflang | Language or language-region code | ISO 639-1 language, ISO 3166-1 Alpha 2 region |
| xhtml:link href | The version's full address | Fully qualified; alternates need not share a domain |
The attribute values in detail
The rel value is always alternate. The hreflang value is the language code, with a region added when the version is regional; a region on its own is invalid. Script variants such as zh-Hant and zh-Hans are supported. Codes outside the standards, for example es-419, are not supported, and reserved values such as EU, UN and UK have no effect, so Google ignores that part of the annotation. Google does not detect language from hreflang or from the lang attribute, and a subdomain named en-gb does not tell Google the audience either, which is why the audience has to be stated through the links.
The href value must include the protocol. A protocol-relative address or a path alone is not accepted. Because alternates do not have to be on the same domain, a set that spans a main domain and a country domain can still be described in one cluster, subject to the rule about where the sitemap is hosted.
What counts toward the limit
The sitemap page gives the limits as 50 MB and 50,000 URLs and does not say whether xhtml:link lines count towards them. Practical suggestion: assume they add to the file size. Each language version is still a url element of its own, so a site with three languages uses three url elements per page. Practical suggestion: divide the limit by the number of versions when you estimate capacity, and remember that the extra lines add to file size.
Every URL lists itself and its pair
Self-reference and return links
Each version must list itself and all the other versions. If two pages do not point to each other, the tags are ignored. In the sitemap this means every member of a cluster carries the same set of xhtml:link lines, including one that points at its own address. A set where the English entry lists the French page but the French entry does not list the English one is an incomplete set.
Practical suggestion: do not write the lines by hand. Keep one list per cluster and let the generator print that list inside every member's url element. Reciprocity then follows from how the file is produced instead of from someone remembering.
The catchall and x-default
For the regions of one language, the documentation asks for a generic catchall page, which can be one of the regional pages. For visitors whose language or region matches none of your versions, there is x-default, a reserved value that needs no language code. The documentation names a country selector or an auto-redirecting home page as examples. In a sitemap it is one more xhtml:link line with hreflang set to x-default. If your home page redirects visitors automatically, read the notes on automatic language redirects first, because Google's multi-regional guidance warns that such redirects can keep users and search engines from all versions.
Pages that exist in fewer languages
Not every page needs every language. The documentation allows leaving out some languages on some pages, as long as a new language page links bidirectionally with the dominant or original version. In a sitemap, you write only the versions that exist. Do not add a placeholder line for a version that has not been published, and do not point it at a similar page to fill the gap.
Large sites: splitting and keeping it fresh
Limits and encoding
According to Google's sitemap documentation, a single sitemap is limited to 50 MB uncompressed or 50,000 URLs, and a larger set must be split. The file must be UTF-8, and tag values must be entity escaped. URLs must be fully qualified and should be the canonical addresses you want shown in search results (Google: Build and submit a sitemap (Opens in a new tab)). Submitting a sitemap is described as merely a hint and does not guarantee crawling.
Index files and hosting
Several sitemaps can be grouped into a sitemap index file, and you can submit just the index. The documentation notes that multiple sitemaps and index files help you track search performance per sitemap in Search Console. Practical suggestion: keep all versions of a content item in the same sitemap file, so a cluster is never split between two files and reciprocity can be checked inside one document.
Location matters. Unless you submit through Search Console, a sitemap affects only URLs in its own directory and below, and the documentation recommends the site root. One sitemap can list URLs from several sites, including different domains, if all of them are verified in Search Console; alternatively each site can reference its own sitemap from its robots.txt.
lastmod and ignored fields
Google uses lastmod only when it is consistently and verifiably accurate, and a changed copyright year is not a significant update. It ignores priority and changefreq. For a language cluster, update the lastmod of the version that changed and leave the others alone. Stamping every member with the same date whenever any member changes teaches Google that the field is unreliable.
You can announce the sitemap through the Sitemaps report in Search Console, through the Search Console API, or with a Sitemap line in robots.txt. The report shows when Googlebot accessed the file and any processing errors.
Generating the file from one source
A hreflang sitemap is hard to maintain by hand and easy to maintain from data. Start by choosing one source that lists every language version: a product database, a CMS, or even a table. Each record needs a cluster identifier, a language code, a region code where relevant, a canonical address and a publication status.
| Input | Held in the source | Used in the sitemap as |
|---|---|---|
| Cluster identifier | Links versions of the same content | Which url entries share one set of lines |
| Language and region | Fields in ISO format | hreflang value |
| Canonical address | The preferred full URL | loc and href values |
| Last significant update | The content system's record | lastmod, only if accurate |
| Publication status | Draft, live or removed | Only live versions are written |
Three rules for the generator, all practical suggestion: write only live and reachable versions, update every member of a cluster at once when any address changes, and print each cluster's full set into each member. When a version is retired, redirect it permanently and remove it from the set, so that no remaining entry points to an address that now redirects.
Mistakes to look for
The table links each typical slip to the rule it breaks in Google's documentation, so a failed check always points at a concrete requirement.
| Mistake | Rule it breaks | Fix |
|---|---|---|
| Entry lacks a line for its own address | Each version lists itself | Add the self-referencing line. |
| Pair lacks the return line | Without return links tags are ignored | Print the same set in every member. |
| Relative or protocol-less href | URLs must be fully qualified | Write the full address with https. |
| Region code on its own | A region alone is invalid | Write language and region together. |
| File saved in another encoding | The sitemap must be UTF-8 | Re-save and escape values. |
| Sitemap hosted below the pages it describes | A sitemap covers its own directory and below | Move it to the site root. |
| All three methods in use | No benefit, harder to manage | Return to a single method. |
| Same lastmod on every member | Must be consistently accurate | Use real update dates. |
The root of these slips is information held in more than one place by hand. Centralizing the generation and running an automatic check before publishing removes the cause instead of repairing the symptoms.
Sitemap checks versus hreflang checks
A general sitemap review looks at whether the file is valid, whether the addresses answer properly and whether they match the canonicals. A hreflang review adds cluster reciprocity, code format and the handling of missing versions. You can run both in one pass, but separate questions find faults faster, because a file can be perfectly valid as a sitemap and still contain a one-way relationship that Google will ignore.
Comparing the three methods side by side
| Aspect | HTML tags | HTTP header | XML sitemap |
|---|---|---|---|
| Where it lives | Page head | Response header | Separate XML file |
| Documented use case | No sitemap or no header control | Non-HTML files such as PDFs | Lists variants per URL with xhtml:link |
| Sameness rule | Same set on every page | Same header on every version | Same lines in every member's entry |
| Template change needed | Yes | Server configuration needed | No |
| Google's view | Equivalent | Equivalent | Equivalent |
The last row is the documentation's statement. The template row is an observation about how each method is deployed. Regardless of method, every member of a cluster must carry the same information.
Validating before and after submission
Step-by-step checks
- Confirm the file is UTF-8, the xhtml namespace is declared on the root element and the XML is well formed.
- Confirm every loc is a fully qualified canonical address.
- Confirm each url entry contains a line for its own address.
- Confirm each entry contains a line for every other member of its cluster, and that the lines are identical across members.
- Check reciprocity: if A lists B, B must list A.
- Check the codes: ISO 639-1 language, ISO 3166-1 Alpha 2 region, no region on its own.
- Look for the catchall page and, if needed, the x-default line.
- Compare the sitemap address of each page with the canonical on the page itself.
- Submit, then read the Sitemaps report for processing errors.
- Fetch every member and confirm it answers directly and does not pass through a redirect chain.
These checks are worth turning into a script: parse the sitemap, rebuild the clusters, test reciprocity and self-reference, and request each address to log the response code. The script's job is simple: find broken clusters before Google does. Reading the Sitemaps report afterwards confirms processing, but the documentation does not describe a screen that verifies each hreflang line, so keep your own check running.
Example scenario: a tour operator with English, Spanish and French pages
Example scenario: a tour operator publishes trip pages in English, Spanish and French under one domain, in three directories. The English and Spanish versions exist for every trip. French exists for only part of the catalogue, and a handful of regional pages have English only. Page templates belong to a web agency with a long release cycle, so the operator chooses the sitemap method.
The operator keeps a table with one row per page version and a cluster identifier per trip. A trip with all three versions writes three url entries, each carrying four lines: English, Spanish, French and x-default pointing to the language selector. A trip with only English and Spanish writes two entries with two lines plus x-default. A regional page with English only gets one entry, with its own line, and no pretend French line.
| Page | Entries in the sitemap | Lines inside each entry |
|---|---|---|
| Trip in three languages | Three url entries | English, Spanish, French and x-default |
| Trip in two languages | Two url entries | English, Spanish and x-default |
| Regional page, English only | One url entry | Its own line only |
When a French page is published later, the operator adds the row. On the next run the generator rewrites that trip's cluster: the French entry appears, and the English and Spanish entries gain a French line. All three entries change in the same run, so the new page links bidirectionally with the original versions. The French lastmod is set to the publication date; the others are updated only if their content changed.
Because the catalogue is large, the operator splits the sitemap by destination, keeping each trip's versions in the same file, and lists the files in a sitemap index referenced from robots.txt. The first week after submission, the team reads the Sitemaps report and runs its own reciprocity check.
Watching the result after launch
Once the sitemap is submitted, the Sitemaps report in Search Console shows when Googlebot accessed the file and any processing errors. The documentation does not describe a view that confirms each hreflang line, so your own reciprocity script remains the main check. The URL Inspection tool shows the canonical Google selected for a single page; if you see an unexpected canonical for a cluster member, compare the cluster's pages and sitemap entries again.
Practical suggestion: run the same validation before and after every addition of a language or country, keep the results, and treat them as a log. When a problem appears, the log shows which change introduced it. Keep lastmod values consistent with that log, changing only the version that actually changed.
Decision rule
- Can you change page templates quickly and safely? If yes, HTML tags are also fine. If not, consider the sitemap.
- Can your versions be listed in one data source? If yes, generate the sitemap from it.
- Do you already keep an accurate sitemap? If yes, add the relationship there. If no, weigh the cost of building one.
- Choose one method only; never keep the same relationship in two places.
- Generate whole clusters at once. Do not publish a half-written cluster.
Pre-submission checklist
- The xhtml namespace is declared on the root element.
- Each url entry lists its own address and all of its pair or cluster.
- All addresses are fully qualified and canonical.
- Codes follow ISO 639-1 and ISO 3166-1 Alpha 2, with no region alone.
- A catchall page exists and x-default is present where it applies.
- Each cluster sits in a single file, and the file is UTF-8.
- The 50,000 URL and 50 MB limits are not exceeded.
- lastmod changes only when the content really changes.
- The sitemap is announced in Search Console and in robots.txt.
Address format should be settled before you generate anything; the localized URL and slug guide covers naming for each language. Once the versions are indexed and begin collecting links from different markets, where those links point is a separate planning question, treated in the international link strategy guide.
Frequently Asked Questions
Which is better for hreflang: HTML tags, the HTTP header or a sitemap?
Google's documentation says the three methods are equivalent from its perspective, and that using all three brings no benefit in Search and makes management harder. Choose by what your site can maintain accurately.
What does a sitemap entry need for hreflang?
The root element declares the xhtml namespace. Each page has its own url element with a loc child, and inside it an xhtml:link element for every version, including itself, with rel alternate, hreflang and href. The order of the links does not matter.
Do the xhtml:link lines count against the URL limit?
The documentation says child elements do not count towards the URL limit. A single sitemap is still limited to 50,000 URLs or 50 MB uncompressed, and each language version is its own url element.
Must every page exist in every language?
No. The documentation allows leaving some languages out on some pages. A new language page should link bidirectionally with the original or dominant versions.
Should I include priority and changefreq?
Google ignores both. It uses lastmod only when it is consistently and verifiably accurate.
Does submitting the sitemap guarantee crawling?
No. The sitemap documentation calls submission merely a hint. The Sitemaps report in Search Console shows when Googlebot accessed the file and any processing errors.
Conclusion
A hreflang sitemap works when every url entry lists itself and its whole cluster with fully qualified, canonical addresses and ISO codes, and when the relationships are reciprocal. Generate the file from one data source, keep a cluster in a single sitemap, stay within the 50,000 URL and 50 MB limits, use one method only and validate before and after you submit. Google's documentation offers no ranking guarantee, and limits and wording can change, so check the current pages before you build.
If you need original content written for each language version, the content writing service page on Akua Adforce explains scope and terms.
Post a comment
Please log in to leave a comment. Login