seo: tynde tag-sider noindex + ud af sitemap, forældreløse sider linket
Build & Deploy / deploy (push) Successful in 3m36s

- tag-siderne (/tags og /tags/*) får "noindex, follow" og udelades af
  sitemap'et: 21 lister med 1-2 indlæg hver trak helhedsindtrykket ned
- /peppol er kun en omdirigering til /nemhandel: noindex og ud af sitemap'et
- /profiler og /ubl kunne kun nås via Cmd/Ctrl+K-paletten (JavaScript, som
  Google ikke følger); nu kort på forsiden under "Mere end et CV"

Sitemap: 44 -> 22 URL'er, alle nås inden for 2 klik fra forsiden.

Claude-Session: https://claude.ai/code/session_012LCTmU2ewo8tnM1dByYAoG
This commit is contained in:
Asger Geel Weirsøe
2026-09-27 07:57:01 +02:00
parent 6640109ab9
commit 7d8ad46d11
7 changed files with 19 additions and 6 deletions
+6
View File
@@ -140,6 +140,12 @@ export default defineConfig({
sitemap({ sitemap({
changefreq: 'weekly', changefreq: 'weekly',
priority: 0.7, priority: 0.7,
// Tag-siderne er noindex (tynde lister), så de hører heller ikke i sitemap'et.
// /peppol er kun en omdirigering til /nemhandel og skal ikke indekseres.
filter: (page) => {
const p = new URL(page).pathname;
return !p.startsWith('/tags') && !p.startsWith('/peppol');
},
serialize(item) { serialize(item) {
const pathname = new URL(item.url).pathname; const pathname = new URL(item.url).pathname;
if (pathname === '/') item.priority = 1.0; if (pathname === '/') item.priority = 1.0;
+5 -2
View File
@@ -11,10 +11,13 @@ interface Props {
modifiedTime?: string; modifiedTime?: string;
tags?: string[]; tags?: string[];
jsonLd?: unknown[]; jsonLd?: unknown[];
// Tynde oversigtssider (fx tags med 1-2 indlæg) skal ikke i Googles indeks,
// men links fra dem skal stadig følges.
noindex?: boolean;
} }
const { const {
title, description, image, type = 'website', title, description, image, type = 'website',
publishedTime, modifiedTime, tags = [], jsonLd = [], publishedTime, modifiedTime, tags = [], jsonLd = [], noindex = false,
} = Astro.props; } = Astro.props;
const pageTitle = title ? `${title} · ${SITE.name}` : `${SITE.title} · Datalog & Technical Solution Architect`; const pageTitle = title ? `${title} · ${SITE.name}` : `${SITE.title} · Datalog & Technical Solution Architect`;
@@ -33,7 +36,7 @@ const graphs = [baseGraph, ...jsonLd];
<meta name="description" content={desc} /> <meta name="description" content={desc} />
<meta name="author" content="Asger Weirsøe" /> <meta name="author" content="Asger Weirsøe" />
<meta name="google-site-verification" content="l5LfnJZFSkVCauhwN9pND_gvxdnZJbx3FM6fpEK8nzE" /> <meta name="google-site-verification" content="l5LfnJZFSkVCauhwN9pND_gvxdnZJbx3FM6fpEK8nzE" />
<meta name="robots" content="index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1" /> <meta name="robots" content={noindex ? "noindex, follow" : "index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1"} />
<link rel="canonical" href={canonical} /> <link rel="canonical" href={canonical} />
<!-- Open Graph --> <!-- Open Graph -->
+3 -2
View File
@@ -16,8 +16,9 @@ interface Props {
modifiedTime?: string; modifiedTime?: string;
tags?: string[]; tags?: string[];
jsonLd?: unknown[]; jsonLd?: unknown[];
noindex?: boolean;
} }
const { title, description, image, type, publishedTime, modifiedTime, tags, jsonLd } = Astro.props; const { title, description, image, type, publishedTime, modifiedTime, tags, jsonLd, noindex } = Astro.props;
--- ---
<!doctype html> <!doctype html>
<Fragment set:html={`<!-- <Fragment set:html={`<!--
@@ -51,7 +52,7 @@ const { title, description, image, type, publishedTime, modifiedTime, tags, json
}); });
})(); })();
</script> </script>
<Head {title} {description} {image} {type} {publishedTime} {modifiedTime} {tags} {jsonLd} /> <Head {title} {description} {image} {type} {publishedTime} {modifiedTime} {tags} {jsonLd} {noindex} />
<ClientRouter /> <ClientRouter />
<!-- Registrér service worker'en (PWA/offline). Genereret af @vite-pwa i build; <!-- Registrér service worker'en (PWA/offline). Genereret af @vite-pwa i build;
is:inline + public-sti så Astro ikke bundler den. 404 i dev = harmløst. --> is:inline + public-sti så Astro ikke bundler den. 404 i dev = harmløst. -->
+2
View File
@@ -88,6 +88,8 @@ const jsonLd = [profilePage, faqPage(faqs)];
{ href: '/chat', title: 'Spørg mit CV', desc: 'En lille AI der har læst mit CV og svarer på spørgsmål om mig. Prøv den af.' }, { href: '/chat', title: 'Spørg mit CV', desc: 'En lille AI der har læst mit CV og svarer på spørgsmål om mig. Prøv den af.' },
{ href: '/status', title: 'Homelab-status', desc: 'Live driftsstatus for de offentlige dele af mit homelab. Self-hosted, selvfølgelig.' }, { href: '/status', title: 'Homelab-status', desc: 'Live driftsstatus for de offentlige dele af mit homelab. Self-hosted, selvfølgelig.' },
{ href: '/now', title: 'Now', desc: 'Hvad jeg roder med lige nu, plus et aktivitets-heatmap fra min egen Gitea.' }, { href: '/now', title: 'Now', desc: 'Hvad jeg roder med lige nu, plus et aktivitets-heatmap fra min egen Gitea.' },
{ href: '/profiler', title: 'Profil-opslag', desc: 'Søgbart opslag over Nemhandel OIOUBL- og Peppol BIS/PINT-profiler: id\'er, dokumenter og typisk brug.' },
{ href: '/ubl', title: 'UBL-tjek', desc: 'Træk en faktura ind og få profil, syntaks og EN 16931-status afkodet. Alt sker i browseren, filen forlader aldrig din maskine.' },
].map((c) => ( ].map((c) => (
<a href={c.href} class="group rounded-2xl border border-border bg-surface/60 p-5 transition-colors hover:border-accent"> <a href={c.href} class="group rounded-2xl border border-border bg-surface/60 p-5 transition-colors hover:border-accent">
<h3 class="font-semibold tracking-tight group-hover:text-accent">{c.title} →</h3> <h3 class="font-semibold tracking-tight group-hover:text-accent">{c.title} →</h3>
+1
View File
@@ -5,6 +5,7 @@
<html lang="da"> <html lang="da">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="robots" content="noindex, follow" />
<meta http-equiv="refresh" content="0; url=/nemhandel" /> <meta http-equiv="refresh" content="0; url=/nemhandel" />
<link rel="canonical" href="https://asger.xn--weirse-fya.dk/nemhandel" /> <link rel="canonical" href="https://asger.xn--weirse-fya.dk/nemhandel" />
<title>NemHandel-opslag</title> <title>NemHandel-opslag</title>
+1 -1
View File
@@ -13,7 +13,7 @@ export async function getStaticPaths() {
} }
const { posts, tag } = Astro.props; const { posts, tag } = Astro.props;
--- ---
<Base title={`#${tag}`} description={`Indlæg om ${tag}.`}> <Base title={`#${tag}`} description={`Indlæg om ${tag}.`} noindex>
<a href="/tags" class="text-sm text-muted hover:text-accent">← Alle tags</a> <a href="/tags" class="text-sm text-muted hover:text-accent">← Alle tags</a>
<h1 class="mt-3 text-4xl font-bold tracking-tight">#{tag}</h1> <h1 class="mt-3 text-4xl font-bold tracking-tight">#{tag}</h1>
<div class="mt-8 grid gap-4"> <div class="mt-8 grid gap-4">
+1 -1
View File
@@ -7,7 +7,7 @@ const counts = new Map<string, number>();
for (const p of posts) for (const t of p.data.tags) counts.set(t, (counts.get(t) ?? 0) + 1); for (const p of posts) for (const t of p.data.tags) counts.set(t, (counts.get(t) ?? 0) + 1);
const tags = [...counts.entries()].sort((a, b) => b[1] - a[1]); const tags = [...counts.entries()].sort((a, b) => b[1] - a[1]);
--- ---
<Base title="Tags" description="Alle emner på bloggen."> <Base title="Tags" description="Alle emner på bloggen." noindex>
<h1 class="text-4xl font-bold tracking-tight">Tags</h1> <h1 class="text-4xl font-bold tracking-tight">Tags</h1>
<div class="mt-8 flex flex-wrap gap-2"> <div class="mt-8 flex flex-wrap gap-2">
{tags.map(([t, n]) => ( {tags.map(([t, n]) => (