diff --git a/apps/web/astro.config.mjs b/apps/web/astro.config.mjs
index 03a0f1d..1453311 100644
--- a/apps/web/astro.config.mjs
+++ b/apps/web/astro.config.mjs
@@ -3,6 +3,7 @@ import node from "@astrojs/node";
export default defineConfig({
site: process.env.PUBLIC_SITE_URL || "https://rf4spotter.ru",
+ trailingSlash: "never",
output: "server",
adapter: node({ mode: "standalone" }),
server: { host: true, port: 4321 },
diff --git a/apps/web/src/pages/sitemap.xml.ts b/apps/web/src/pages/sitemap.xml.ts
index ddf35bc..de2db9d 100644
--- a/apps/web/src/pages/sitemap.xml.ts
+++ b/apps/web/src/pages/sitemap.xml.ts
@@ -24,7 +24,9 @@ export const GET: APIRoute = async ({ site }) => {
if (paths.size > 49000) throw new Error("Sitemap index required");
if (rows.length < 1000) break;
}
- const xml = `${[...paths].map(path => `${escapeXml(new URL(path, origin).toString())}`).join("")}`;
+ // Normalize paths: never use trailing slash (S03)
+ const normalized = [...paths].map(p => p.replace(/\/$/, "") || "/");
+ const xml = `${normalized.map(path => `${escapeXml(new URL(path, origin).toString())}`).join("")}`;
lastGood = { origin, xml, at: Date.now() };
return output(xml);
} catch {