Sitemap
XML sitemap generation for SvelteKit applications.
SitemapUrl
Interface describing a single URL entry in a sitemap.
import type { SitemapUrl } from '@repo/utils'
interface SitemapUrl {
loc: string
lastmod?: string // ISO 8601 date
changefreq?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never'
priority?: number // 0.0 to 1.0
}
generateSitemap
Generates a sitemap XML string from an array of SitemapUrl objects. Includes standard sitemap namespaces (xhtml, mobile, news, image, video).
import { generateSitemap } from '@repo/utils'
function generateSitemap(urls: SitemapUrl[]): string
Example
import { generateSitemap } from '@repo/utils'
import type { SitemapUrl } from '@repo/utils'
const urls: SitemapUrl[] = [
{ loc: 'https://example.com/', priority: 1.0, changefreq: 'daily' },
{ loc: 'https://example.com/about', priority: 0.8 },
{ loc: 'https://example.com/blog', lastmod: '2024-06-15', changefreq: 'weekly' },
]
const xml = generateSitemap(urls)
// Returns formatted XML:
// <?xml version="1.0" encoding="UTF-8"?>
// <urlset xmlns="https://www.sitemaps.org/schemas/sitemap/0.9" ...>
// <url>
// <loc>https://example.com/</loc>
// <changefreq>daily</changefreq>
// <priority>1.0</priority>
// </url>
// ...
// </urlset>
getSitemapOnFileBased
Generates sitemap URLs from SvelteKit's file-based routing. Automatically strips route file endings, parenthesized layout groups, and dynamic [param] routes.
import { getSitemapOnFileBased } from '@repo/utils'
function getSitemapOnFileBased(
url: URL,
files: Record<string, () => Promise<unknown>>
): SitemapUrl[]
Example
Use with SvelteKit's import.meta.glob in a +server.ts sitemap endpoint:
import { getSitemapOnFileBased, generateSitemap } from '@repo/utils'
// In src/routes/sitemap.xml/+server.ts
export async function GET({ url }) {
const pages = import.meta.glob('/src/routes/**/+page.svelte')
const urls = getSitemapOnFileBased(url, pages)
// Dynamic routes like /src/routes/blog/[slug]/+page.svelte are excluded
// Layout groups like /src/routes/(app)/dashboard/+page.svelte become /dashboard
return new Response(generateSitemap(urls), {
headers: { 'Content-Type': 'application/xml' },
})
}
Given these files:
/src/routes/+page.svelte -> { loc: 'https://example.com' }
/src/routes/(app)/dashboard/+page.svelte -> { loc: 'https://example.com/dashboard' }
/src/routes/blog/+page.svelte -> { loc: 'https://example.com/blog' }
/src/routes/blog/[slug]/+page.svelte -> excluded (dynamic route)