Files
pw/src/components/Head.astro
T
Asger Geel Weirsøe 7d8ad46d11
Build & Deploy / deploy (push) Successful in 3m36s
seo: tynde tag-sider noindex + ud af sitemap, forældreløse sider linket
- 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
2026-09-27 07:57:01 +02:00

118 lines
5.6 KiB
Plaintext

---
import { SITE } from '../consts';
import { baseGraph } from '../seo';
interface Props {
title?: string;
description?: string;
image?: string;
type?: 'website' | 'article';
publishedTime?: string;
modifiedTime?: string;
tags?: string[];
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 {
title, description, image, type = 'website',
publishedTime, modifiedTime, tags = [], jsonLd = [], noindex = false,
} = Astro.props;
const pageTitle = title ? `${title} · ${SITE.name}` : `${SITE.title} · Datalog & Technical Solution Architect`;
const desc = description ?? SITE.description;
// 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];
---
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>{pageTitle}</title>
<meta name="description" content={desc} />
<meta name="author" content="Asger Weirsøe" />
<meta name="google-site-verification" content="l5LfnJZFSkVCauhwN9pND_gvxdnZJbx3FM6fpEK8nzE" />
<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} />
<!-- Open Graph -->
<meta property="og:type" content={type} />
<meta property="og:site_name" content={SITE.name} />
<meta property="og:title" content={pageTitle} />
<meta property="og:description" content={desc} />
<meta property="og:url" content={canonical} />
<meta property="og:locale" content="da_DK" />
<meta property="og:image" content={ogImage} />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta property="og:image:alt" content={pageTitle} />
{type === 'article' && publishedTime && <meta property="article:published_time" content={publishedTime} />}
{type === 'article' && modifiedTime && <meta property="article:modified_time" content={modifiedTime} />}
{type === 'article' && <meta property="article:author" content="Asger Weirsøe" />}
{type === 'article' && tags.map((t) => <meta property="article:tag" content={t} />)}
<!-- Twitter -->
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content={pageTitle} />
<meta name="twitter:description" content={desc} />
<meta name="twitter:image" content={ogImage} />
<meta name="theme-color" content="#0b0f17" media="(prefers-color-scheme: dark)" />
<meta name="theme-color" content="#f6f8fb" media="(prefers-color-scheme: light)" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
<link rel="manifest" href="/site.webmanifest" />
<link rel="sitemap" href="/sitemap-index.xml" />
<link rel="alternate" type="application/rss+xml" title={SITE.name} href="/rss.xml" />
<!-- Mastodon-verifikation: usynligt rel=me i head (kræver ingen JS) -->
<link rel="me" href="https://mastodon.social/@asgerweirsoee" />
{graphs.map((g) => <script type="application/ld+json" set:html={JSON.stringify(g)} />)}
<!-- Matomo (site 2) via first-party proxy /_a/: neutrale navne, så content-blockers ikke matcher "matomo".
Lagt direkte i kilden fordi HTML-minify dropper det valgfrie </head> som NPMplus' sub_filter ellers injicerede på. -->
<script is:inline>
var _paq = (window._paq = window._paq || []);
_paq.push(['setDomains', ['*.weirsoe.dk', '*.xn--weirse-fya.dk']]);
_paq.push(['setVisitorCookieTimeout', 31536000]); // visitor-cookie lever 1 år (sekunder)
_paq.push(['enableLinkTracking']);
// Enhedsmodel (Custom Dimension 2): grov enheds-kohorte ud fra skaerm (logiske pt) + DPR.
// Apple maskerer GPU-strengen, saa 6,1-tommer-generationen kan ikke splittes finere end gruppe.
(function () {
try {
var w = screen.width, h = screen.height, dpr = Math.round(window.devicePixelRatio || 1);
var k = Math.min(w, h) + 'x' + Math.max(w, h) + '@' + dpr;
var ua = navigator.userAgent || '';
var isApple = /iPhone|iPad|iPod/.test(ua) || (/Macintosh/.test(ua) && navigator.maxTouchPoints > 1);
var iphone = {
'320x568@2': 'iPhone SE(1)/5s',
'375x667@2': 'iPhone SE(2/3)/6/7/8',
'414x736@3': 'iPhone 6+/7+/8+ Plus',
'375x812@3': 'iPhone X/XS/11Pro/12mini/13mini',
'390x844@3': 'iPhone 12/13/14/16e (6,1 tomme notch)',
'393x852@3': 'iPhone 14Pro/15/15Pro/16',
'402x874@3': 'iPhone 16Pro',
'414x896@2': 'iPhone XR/11',
'414x896@3': 'iPhone XSMax/11ProMax',
'428x926@3': 'iPhone 12ProMax/13ProMax/14Plus',
'430x932@3': 'iPhone 14ProMax/15Plus/15ProMax/16Plus',
'440x956@3': 'iPhone 16ProMax'
};
var model = iphone[k] ? iphone[k] : (isApple ? ('Apple ukendt ' + k) : ('Andet ' + k + ' ' + (navigator.platform || '?')));
_paq.push(['setCustomDimension', 2, model]);
} catch (e) {}
})();
_paq.push(['trackPageView']);
(function () {
var u = '/_a/';
_paq.push(['setTrackerUrl', u + 'a']);
_paq.push(['setSiteId', '2']);
var d = document, g = d.createElement('script'), s = d.getElementsByTagName('script')[0];
g.async = true; g.src = u + 'a.js'; s.parentNode.insertBefore(g, s);
})();
</script>