/** * Serializes sitemap entries to an XML STRING with an XSL stylesheet reference, * so /sitemap.xml renders as a readable table in the browser (not raw XML) while * staying a valid sitemap for crawlers. * * Why this exists alongside the Next MetadataRoute sitemap: Next's app/sitemap.ts * (returning SitemapEntry[]) does NOT let you inject . To get * the styled table, serve a custom route that returns this string instead: * * // app/sitemap.xml/route.ts * import { buildSitemapXml } from '@intecion/ipal-kit' * import { sitemap } from '@/lib/content' // your entries source * export const dynamic = 'force-dynamic' * export async function GET() { * const entries = await sitemap() * const xml = buildSitemapXml(entries, { stylesheetUrl: '/sitemap.xsl' }) * return new Response(xml, { * headers: { 'Content-Type': 'application/xml; charset=utf-8' }, * }) * } * * Put sitemap.xsl in the project's /public (copy from the plugin's assets, or * serve it from a route). The points browsers at it; crawlers * ignore it and read the XML. Include hreflang alternates as . * * NOTE: if you use this custom route, DON'T also keep app/sitemap.ts — pick one * (the styled route OR the Next MetadataRoute). Two sitemaps at different paths * confuse crawlers. */ export function buildSitemapXml(entries, opts = {}) { const { stylesheetUrl } = opts; const esc = (s)=>s.replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"').replace(/'/g, '''); const urls = entries.map((e)=>{ const parts = [ ` ${esc(e.url)}` ]; if (e.lastModified) { const iso = e.lastModified instanceof Date ? e.lastModified.toISOString() : String(e.lastModified); parts.push(` ${esc(iso)}`); } if (e.changeFrequency) parts.push(` ${e.changeFrequency}`); if (typeof e.priority === 'number') parts.push(` ${e.priority}`); // hreflang alternates const alternates = e.alternates?.languages; if (alternates) { for (const [lang, href] of Object.entries(alternates)){ if (typeof href === 'string') { parts.push(` `); } } } return ` \n${parts.join('\n')}\n `; }).join('\n'); const stylesheet = stylesheetUrl ? `\n` : ''; return `\n` + stylesheet + `\n` + urls + `\n`; } //# sourceMappingURL=buildSitemapXml.js.map