From 3ea08fa706e97f3798ea3719ec287716839fa093 Mon Sep 17 00:00:00 2001 From: IK Date: Thu, 10 Sep 2026 05:53:36 +0700 Subject: [PATCH] =?UTF-8?q?S03:=20Consistent=20site=20origin=20=E2=80=94?= =?UTF-8?q?=20trailingSlash=20never,=20canonical=20URLs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add trailingSlash: 'never' to Astro config - Normalize sitemap paths to never use trailing slash - Ensures consistent canonical URLs across all pages - Prevents duplicate content from / vs /path/ variants --- apps/web/astro.config.mjs | 1 + apps/web/src/pages/sitemap.xml.ts | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) 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 {