import type { APIRoute } from 'astro'; import { site } from '@shared/lib/site'; export const prerender = true; // Port of preview/pages/sitemap.liquid: one entry per page, file-style URLs // (build.format 'file'), index pages collapse to their directory URL. // Entry order mirrors the Eleventy `pages` collection: top-level pages first, // then nested ones, each group in reverse-alphabetical order. const pages = import.meta.glob('./**/*.astro'); const urls = Object.keys(pages) .map((file) => file.replace(/^\.\//, '').replace(/\.astro$/, '.html')) .sort((a, b) => { const depthA = a.split('/').length; const depthB = b.split('/').length; if (depthA !== depthB) return depthA - depthB; // byte-wise, descending — matches the Eleventy `pages` collection order return a < b ? 1 : -1; }) .map((path) => { if (path === 'index.html') return '/'; if (path.endsWith('/index.html')) return `/${path.slice(0, -'index.html'.length)}`; return `/${path}`; }); const escapeXml = (value: string) => value .replace(/&/g, '&') .replace(//g, '>') .replace(/"/g, '"') .replace(/'/g, '''); export const GET: APIRoute = () => { const environment = process.env.NODE_ENV || 'production'; const baseUrl = environment !== 'development' ? site.previewUrl : ''; // same shape as Liquid's `'now' | date_to_xmlschema` (UTC, +00:00 suffix) const lastModified = new Date().toISOString().replace(/\.\d{3}Z$/, '+00:00'); const entries = urls .map( (url) => ` ${escapeXml(`${baseUrl}${url}`)} ${lastModified} `, ) .join('\n'); const body = ` ${entries} `; return new Response(body, { headers: { 'Content-Type': 'application/xml; charset=utf-8', }, }); };