sitemap.xml
Every built page, with priority and changefreq rules, extra sources, hreflang alternates and index mode.
Enabled by default. sitemap: false turns it off.
Where the URLs come from
- The pages Astro reports in
astro:build:done, including i18n fallback routes. - Entries returned by
sources.
For each discovered page the integration opens its HTML once and reads:
lastmodfrom the file’s modification date,<meta http-equiv="refresh">at the top: the page is a redirect and is dropped,<meta name="robots" content="noindex">(orgooglebot) in the<head>: dropped unlessexcludeNoindex: false,data-sitemap-changefreqanddata-sitemap-priorityon any JSON-LD<script>tag.
Always excluded: /404, /500, paths starting with /_, and the generated files themselves
(sitemap.xml, sitemap-index.xml, robots.txt, llms.txt, rss.xml, feed.xml). The build
log lists every path dropped by these rules. Segments like /api/ or /drafts/ are not excluded
automatically; use exclude or filter.
Options
interface SitemapOptions {
siteUrl?: string
sources?: SitemapSource[]
exclude?: (string | RegExp)[]
filter?: (url: string) => boolean
excludeNoindex?: boolean
priority?: PriorityRule[]
changefreq?: ChangefreqRule[]
localeAgnosticRules?: boolean
output?: {
mode?: 'single' | 'index'
maxUrls?: number
filename?: string
}
audit?: {
warnOnEmpty?: boolean
errorOnDuplicates?: boolean
}
serialize?: (entry: ResolvedSitemapEntry) =>
ResolvedSitemapEntry | undefined | Promise<ResolvedSitemapEntry | undefined>
i18n?: I18nOptions
}
type SitemapSource = () => Promise<SitemapEntry[]>
interface SitemapEntry {
loc: string
lastmod?: string
priority?: number
changefreq?: Changefreq
}
interface PriorityRule { pattern: string | RegExp; priority: number; allLocales?: boolean }
interface ChangefreqRule { pattern: string | RegExp; changefreq: Changefreq; allLocales?: boolean }
interface I18nOptions { defaultLocale: string; locales: Record<string, string> }
| Option | Default | Effect |
|---|---|---|
siteUrl |
Astro site |
Host for <loc>; base is appended either way |
sources |
[] |
Extra entries; relative loc values are prefixed with site and base |
exclude |
[] |
Path prefix or RegExp; discovered pages only |
filter |
– | Receives the full URL, false drops it; discovered pages only |
excludeNoindex |
true |
Drop noindex pages |
priority, changefreq |
[] |
Rules by path; first match wins |
localeAgnosticRules |
false |
Match rules against the path without locale prefix |
output.mode |
'single' |
'index' writes sitemap-index.xml plus sitemap-1.xml … |
output.maxUrls |
50000 |
More entries switch to index mode automatically |
output.filename |
sitemap.xml |
Single-file mode only |
serialize |
– | Transform or drop (undefined) each resolved entry, sources included |
i18n |
Astro i18n |
Locale path → hreflang code, for alternates |
exclude and filter do not touch entries from sources; filter those in the source itself or
in serialize.
Built-in priority and changefreq
Without a matching rule:
- priority by path depth:
/1.0, one segment 0.9, two 0.8, deeper 0.7; - changefreq
weeklyfor/and paths containing/blog/,/artikel/,/insights/,/news/,/post/,/posts/,/update/or/updates/, otherwisemonthly.
Depth is counted below the base path and ignores a known locale prefix, so /de/ scores like
/. Explicit values from sources or data-sitemap-* attributes win over rules.
// Entries at /, /blog/, /blog/hello-world/ and /about/, all without rules
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated by @casoon/astro-site-files -->
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://example.com/</loc>
<lastmod>2026-09-01</lastmod>
<changefreq>weekly</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>https://example.com/blog/</loc>
<lastmod>2026-09-01</lastmod>
<changefreq>weekly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://example.com/blog/hello-world/</loc>
<lastmod>2026-09-01</lastmod>
<changefreq>weekly</changefreq>
<priority>0.8</priority>
</url>
<url>
<loc>https://example.com/about/</loc>
<lastmod>2026-09-01</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
</urlset>
Multilingual sites
With Astro’s i18n config set, entries that differ only in their locale prefix are grouped. Each
of them gets one <xhtml:link rel="alternate" hreflang="…" href="…"/> per variant plus an
x-default link to the defaultLocale variant. Set sitemap.i18n only when the mapping differs
from Astro’s.
Your own priority and changefreq rules match the real, prefixed path. To write a rule once for
all languages, set localeAgnosticRules: true, or allLocales: true on a single rule:
siteFiles({
sitemap: {
localeAgnosticRules: true,
changefreq: [
{ pattern: '/blog/', changefreq: 'daily' },
{ pattern: '/de/aktion/', changefreq: 'hourly', allLocales: false },
],
},
})
Extra entries
siteFiles({
sitemap: {
exclude: ['/drafts/'],
priority: [{ pattern: '/blog/', priority: 0.9 }],
sources: [
async () => [{ loc: '/landing/spring/', lastmod: '2026-09-01' }],
],
},
})
Audit hints
sitemap/no-site-url, sitemap/empty-sitemap, sitemap/duplicate-urls and
sitemap/invalid-priority. See build-time audit.