How to Generate a Dynamic sitemap.xml in SvelteKit (with Code Example)
Learn how to generate a dynamic sitemap.xml in SvelteKit with +server.ts. Boost SEO and improve search engine indexing with this step-by-step guide and code example.
If you're building with SvelteKit and want to improve how your site gets discovered by search engines, setting up a sitemap.xml
is a good place to start. This guide walks through how to generate a dynamic sitemap in SvelteKit using +server.ts
, and how to optionally include lastmod
timestamps for better indexing.
Why Use a Sitemap?
A sitemap is a structured list of your site’s URLs. Search engines use it to understand what content exists on your site and when it was last updated. It becomes particularly important if:
Your site has dynamic content (e.g., blog posts or product pages)
Not all pages are easily discoverable via internal links
You want faster indexing after publishing or updating content
Step 1: Create a Dynamic Sitemap Route in SvelteKit
Create a file at:
src/routes/sitemap.xml/+server.ts
paste the following code:
const baseUrl = 'https://example.com';
export async function GET() {
const pages = [
{ url: '/', lastmod: '2024-12-15' },
{ url: '/about', lastmod: '2024-12-10' }
];
const sitemap = `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
${pages
.map(
(page) => `
<url>
<loc>${new URL(page.url, baseUrl)}</loc>
<lastmod>${page.lastmod}</lastmod>
</url>`
)
.join('')}
</urlset>`;
return new Response(sitemap, {
headers: {
'Content-Type': 'application/xml'
}
});
}
When you visit /sitemap.xml
, you should see a valid XML response with your listed pages.
How the Code Works
baseUrl
is your site's root URL. Update this to your production domain.The
pages
array lists the routes you want indexed. You can hardcode static routes or dynamically fetch content.Each item is converted into a valid
<url>
block inside the XML using.map()
.The
Content-Type
header ensures the browser and crawlers interpret it as XML.
Adding Dynamic Routes
If you have dynamic content like blog posts or documentation pages, you can fetch those slugs and generate URLs programmatically. For example:
const posts = await getAllBlogSlugs();
const pages = posts.map((slug) => ({
url: `/blog/${slug}`,
lastmod: '2024-12-20' // optionally use actual update timestamps
}));
Combine these with your static pages to build a full sitemap.
Should You Include the lastmod
Tag?
The lastmod
field indicates when a page was last modified. It's optional but can help search engines prioritize recent updates.
Use lastmod
if:
Your content is regularly updated
You want faster reindexing of updated pages
Your SEO strategy benefits from content freshness
It’s less critical if:
Your content is mostly static
Your site is small and easily crawlable
You don’t track publish/update dates
If omitted, your sitemap remains valid, but may be crawled less efficiently.
Validation and Submission
Once implemented, test your sitemap:
Visit
/sitemap.xml
and inspect the outputValidate it using tools like Google’s sitemap validator
To notify search engines, add this line to your robots.txt
file:
Sitemap: https://example.com/sitemap.xml
You can also submit it via Google Search Console for faster indexing.
Conclusion
A dynamic sitemap helps search engines crawl and index your SvelteKit site more effectively. Whether you're working with a handful of static pages or hundreds of dynamic routes, implementing a sitemap with +server.ts is a lightweight, scalable approach. By optionally including lastmod data, you give crawlers even more context for what’s new and relevant.
If your site evolves over time, your sitemap should evolve with it—and this setup makes that straightforward.