/**
* Serializes sitemap entries to a clean, indented XML STRING — valid for crawlers
* and readable in the browser as the native XML tree (indented, collapsible,
* syntax-highlighted by the browser itself).
*
* NO XSLT stylesheet: browsers (Chrome et al.) are REMOVING XSLT support, so a
* approach is a dead end — it shows a deprecation warning now
* and will break soon. Instead we serve plain XML with the correct Content-Type;
* the browser renders its built-in formatted XML view (the "code tree" look) with
* no transformation needed.
*
* // app/sitemap.xml/route.ts
* import { buildSitemapXml } from '@intecion/ipal-kit'
* import { sitemap } from '@/lib/content'
* export const dynamic = 'force-dynamic'
* export async function GET() {
* const entries = await sitemap()
* const xml = buildSitemapXml(entries)
* return new Response(xml, {
* headers: { 'Content-Type': 'application/xml; charset=utf-8' },
* })
* }
*
* The indentation makes the raw XML pleasant to read; the browser's default XML
* viewer adds the tree/fold UI. Crawlers read the XML as usual.
*
* NOTE: if you use this custom route, DON'T also keep app/sitemap.ts — pick one
* (this route OR the Next MetadataRoute). Two sitemaps confuse crawlers.
*/ export function buildSitemapXml(entries) {
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}`);
}
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');
return `\n` + `\n` + urls + `\n`;
}
//# sourceMappingURL=buildSitemapXml.js.map