To add a sitemap to an Astro site, run npx astro add sitemap, set site in astro.config.mjs, and build. Astro writes sitemap-index.xml and sitemap-0.xml into dist/ on every build, listing every static page, including pages generated by getStaticPaths().
Key Takeaways
- One command installs and registers the integration:
npx astro add sitemap.- The integration does nothing without
site, because sitemaps need absolute URLs.- Use
filterto keep pages like/thank-you/out.- On-demand routes aren’t discovered automatically; list them with
customPages.
Install it
npx astro add sitemap
astro add installs @astrojs/sitemap and adds it to your config. Then set your production URL:
// astro.config.mjs
import { defineConfig } from 'astro/config';
import sitemap from '@astrojs/sitemap';
export default defineConfig({
site: 'https://www.example.com',
integrations: [sitemap()],
});
Run npm run build and check dist/sitemap-index.xml. It points to sitemap-0.xml, which lists your URLs. Large sites get sitemap-1.xml and so on; the integration splits at 45,000 entries by default (entryLimit).
Keep private pages out
sitemap({
filter: (page) =>
!page.includes('/thank-you/') &&
!page.includes('/admin/') &&
!page.endsWith('/404/'),
})
filter receives the full URL and keeps pages where it returns true. Anything with a noindex meta tag should also be filtered here, so you don’t send search engines mixed signals.
Add lastmod
lastmod helps search engines prioritise recrawling changed pages. Set it per URL with serialize:
// astro.config.mjs
import { defineConfig } from 'astro/config';
import sitemap from '@astrojs/sitemap';
import fs from 'node:fs';
import path from 'node:path';
import matter from 'gray-matter';
const blogDir = './src/content/blog';
const updated = new Map(
fs.readdirSync(blogDir).filter((f) => /\.mdx?$/.test(f)).map((f) => {
const { data } = matter(fs.readFileSync(path.join(blogDir, f), 'utf8'));
return [f.replace(/\.mdx?$/, ''), data.updatedDate ?? data.pubDate];
}),
);
export default defineConfig({
site: 'https://www.example.com',
integrations: [
sitemap({
serialize(item) {
const slug = item.url.match(/\/blog\/([^/]+)\/?$/)?.[1];
const date = slug && updated.get(slug);
if (date) item.lastmod = new Date(date).toISOString();
return item;
},
}),
],
});
Only set lastmod from real content dates. A build timestamp on every URL tells search engines nothing. (gray-matter is a separate install: npm install -D gray-matter.)
changefreq and priority are also supported, but Google has said it ignores them, so they’re not worth maintaining.
On-demand pages
The integration builds the sitemap from the routes Astro prerenders. Pages rendered on request (prerender = false) aren’t included, because their URLs aren’t known at build time. Add the ones you want indexed:
sitemap({
customPages: ['https://www.example.com/store/', 'https://www.example.com/search/'],
})
Tell crawlers where it is
Add one line to public/robots.txt:
Sitemap: https://www.example.com/sitemap-index.xml
Then submit sitemap-index.xml in Google Search Console and Bing Webmaster Tools. The robots.txt tip shows how to generate this file from site so the domain lives in one place.
You can also link it from your <head> for discovery:
<link rel="sitemap" href="/sitemap-index.xml" />
Common problems
No sitemap in dist/. site isn’t set. The build log shows a warning from the integration.
Wrong domain in URLs. site is set to a staging or preview URL. Use the production origin.
Trailing slashes don’t match your links. The sitemap follows your trailingSlash and build.format settings; see Astro trailingSlash and build.format.
If you’re working in a Komal theme, the config file is covered in Astro configuration. The sitemap is one item on the Astro SEO checklist. For the full option list, the official @astrojs/sitemap docs are the reference.
FAQ
Does the Astro sitemap include dynamic routes?
Yes, for static builds. Any page generated by getStaticPaths() is included, because the integration reads the final list of built pages. On-demand routes need customPages.
Where is the Astro sitemap URL?
At /sitemap-index.xml on your domain. It links to one or more sitemap-N.xml files.