/** * Pure utilities for generating sitemap XML. * * Extracted from the route handler so the logic can be unit-tested without * spinning up an HTTP server. */ import type { Site } from "./site-context"; import type { SitemapEntry } from "./sitemap-routes"; /** * Escape a string for safe XML attribute / text content embedding. */ function xmlEscape(s: string): string { return s .replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """) .replace(/'/g, "'"); } /** * Generate a single `` element for a given entry on a site. */ export function urlElement(site: Site, entry: SitemapEntry): string { const loc = `https://${site.domain}${entry.path}`; return ` ${xmlEscape(loc)} ${new Date().toISOString()} ${xmlEscape(entry.changefreq)} ${entry.priority.toFixed(1)} `; } /** * Generate the full sitemap XML for a given site and its route entries. */ export function generateSitemap(site: Site, entries: SitemapEntry[]): string { const urls = entries.map((e) => urlElement(site, e)).join("\n"); return ` ${urls} `; }