From fc7ca339a1d17d4832ceda76df0b95fef9e61220 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asger=20Geel=20Weirs=C3=B8e?= Date: Thu, 10 Sep 2026 20:15:00 +0200 Subject: [PATCH] =?UTF-8?q?seo:=20=C3=A9n=20kanonisk=20URL-form=20?= =?UTF-8?q?=E2=80=94=20uden=20afsluttende=20skr=C3=A5streg?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Google kendte 41 af sitemapets 44 URL'er som "Webadressen er ikke kendt af Google". Årsagen var at siden fandtes i to former: de interne links peger alle på no-slash (/blog, /cv, /tags/proxmox), mens sitemap og brugte skråstreg-formen. Origin serverer begge med 200 uden redirect, så Googles linkbaserede opdagelse ramte kun det ene sæt, og sitemapets sæt blev aldrig opdaget. Nu peger canonical, sitemap og RSS alle på no-slash-formen, som de interne links i forvejen brugte. lastmod slås stadig op på Astros egne ruter (som har skråstregen) FØR URL'en strippes, så sitemapets 44 lastmod-datoer er uændrede. Claude-Session: https://claude.ai/code/session_0198n4owY35jQpwht1wCGzfh --- astro.config.mjs | 4 ++++ src/components/Head.astro | 6 +++++- src/pages/rss.xml.js | 5 ++++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/astro.config.mjs b/astro.config.mjs index 59f004e..629a00c 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -145,6 +145,10 @@ export default defineConfig({ if (pathname === '/') item.priority = 1.0; const lastmod = lastmodByRoute.get(pathname); if (lastmod) item.lastmod = lastmod; + // Samme kanoniske form som og de interne links: + // uden afsluttende skråstreg. Slås lastmod op FØR strippet, fordi + // lastmodByRoute er nøglet på Astros egne ruter (som har skråstregen). + if (pathname !== '/') item.url = item.url.replace(/\/$/, ''); return item; }, }), diff --git a/src/components/Head.astro b/src/components/Head.astro index 03eb9c5..080d36f 100644 --- a/src/components/Head.astro +++ b/src/components/Head.astro @@ -19,7 +19,11 @@ const { const pageTitle = title ? `${title} · ${SITE.name}` : `${SITE.title} — Datalog & Technical Solution Architect`; const desc = description ?? SITE.description; -const canonical = new URL(Astro.url.pathname, SITE.url).href; +// Kanonisk form er UDEN afsluttende skråstreg. Origin serverer begge former med +// 200, og de interne links peger alle på no-slash — så canonical og sitemap skal +// gøre det samme, ellers opdager Google to adskilte sæt af de samme sider. +const canonicalPath = Astro.url.pathname.replace(/\/$/, '') || '/'; +const canonical = new URL(canonicalPath, SITE.url).href; const ogImage = new URL(image ?? '/og.png', SITE.url).href; const graphs = [baseGraph, ...jsonLd]; --- diff --git a/src/pages/rss.xml.js b/src/pages/rss.xml.js index a1946e4..81b9b26 100644 --- a/src/pages/rss.xml.js +++ b/src/pages/rss.xml.js @@ -9,11 +9,14 @@ export async function GET(context) { title: SITE.title, description: SITE.description, site: context.site, + // Samme kanoniske URL-form som canonical og sitemap: uden afsluttende + // skråstreg. @astrojs/rss tilføjer den ellers selv (default true). + trailingSlash: false, items: posts.map((p) => ({ title: p.data.title, description: p.data.description, pubDate: p.data.date, - link: `/blog/${p.id}/`, + link: `/blog/${p.id}`, })), customData: `da-dk`, });