An XML sitemap lists the URLs you want search engines to crawl and index. It helps them discover pages faster, especially on new sites, large sites, and pages with few internal links. It doesn’t guarantee indexing, but a clean sitemap is one of the simplest technical SEO wins.
The format
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://example.com/</loc>
<lastmod>2026-10-28</lastmod>
</url>
<url>
<loc>https://example.com/blog/install-nginx-ubuntu/</loc>
<lastmod>2026-09-14T08:30:00+00:00</lastmod>
</url>
</urlset>
- loc: the full, absolute, canonical URL (same protocol, host and trailing-slash style as the site).
- lastmod: when the content last changed meaningfully. Google uses it if it’s consistently accurate. Don’t set every URL to today’s date on every build.
- changefreq and priority: Google ignores them. You can leave them out.
Limits and sitemap indexes
One sitemap file can hold at most 50,000 URLs and 50 MB (uncompressed). Larger sites split URLs into several files, and list them in 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-pages.xml</loc></sitemap>
<sitemap><loc>https://example.com/sitemap-posts.xml</loc></sitemap>
</sitemapindex>
Splitting by type (pages, posts, products) also makes Search Console’s indexing reports easier to read. Sitemaps can be gzip-compressed (sitemap.xml.gz).
What to include
Include only URLs that are:
- canonical (not duplicates, not parameter variants);
- indexable (no noindex, not blocked in robots.txt);
- returning 200 (no redirects, no 404s).
Exclude: redirected URLs, paginated archives you don’t care about, internal search pages, thank-you pages, staging URLs. A sitemap full of redirects and 404s teaches Google to trust it less.
Generating sitemaps
| Platform | How |
|---|---|
| WordPress | Built-in /wp-sitemap.xml, or SEO plugins (Yoast, Rank Math). See WordPress sitemaps |
| Astro | @astrojs/sitemap integration |
| Next.js | app/sitemap.ts |
| Hugo / Jekyll | Built-in or plugin |
| Laravel | spatie/laravel-sitemap |
| Django | django.contrib.sitemaps |
| Any site | Crawl-based generators (Screaming Frog), or a script from your database |
For dynamic sites, generate from the database (so new products appear immediately), and cache the result rather than rebuilding it on every request.
Special sitemaps
- Image and video extensions add media details for media-heavy sites.
- News sitemaps for Google News publishers (articles from the last two days).
- hreflang alternates can be declared in sitemaps for multilingual sites. See the hreflang guide.
Tell search engines
- Add it to robots.txt:
Sitemap: https://example.com/sitemap-index.xml. See the robots.txt guide. - Submit it in Google Search Console → Sitemaps, and in Bing Webmaster Tools. See Google Search Console setup.
- Bing and others support IndexNow for instant notification of changed URLs.
(Google retired the old “ping” endpoint, so submitting through Search Console and robots.txt is the way.)
Serving it correctly
- Return
200withContent-Type: application/xml(ortext/xml). - Make it reachable without login, cookies or WAF challenges for crawlers.
- Check it with
curl -I https://example.com/sitemap-index.xml.
Reading Search Console reports
| Status | Meaning |
|---|---|
| Success | Fetched and parsed; shows discovered URLs |
| Couldn’t fetch | Wrong URL, blocked, server error, or timeout |
| Has errors | Invalid XML, wrong namespace, bad dates |
Then check Pages (indexing) filtered by sitemap: “Discovered – currently not indexed” and “Crawled – currently not indexed” usually point to quality or internal-linking problems, not sitemap problems.
Common mistakes
- HTTP URLs, or the wrong host (www vs non-www) in
<loc>. - Including noindex, redirected or 404 URLs.
lastmodset to the build time for every URL.- A stale sitemap after a migration. Regenerate it with the new URLs. See website migration SEO.
- Listing the sitemap in robots.txt for one host, while the URLs inside belong to another.
Quick reference
| Item | Value |
|---|---|
| Max per file | 50,000 URLs / 50 MB |
| Many files | Sitemap index |
| Useful tags | loc, lastmod |
| Ignored by Google | changefreq, priority |
| Include | Canonical, indexable, 200 URLs |
| Submit | robots.txt + Search Console + Bing |
Related: technical SEO on your own server and canonical URLs.