Put the language switch in the header on every translated page
Build & Deploy / deploy (push) Successful in 2m31s

Claude-Session: https://claude.ai/code/session_012LCTmU2ewo8tnM1dByYAoG
This commit is contained in:
Asger Geel Weirsøe
2026-10-29 18:24:00 +01:00
parent 653b428670
commit 0105f1576d
10 changed files with 20 additions and 37 deletions
+7 -1
View File
@@ -1,6 +1,8 @@
---
import { NAV, NAV_EN, SITE } from '../consts';
const { lang } = Astro.props as { lang?: 'da' | 'en' };
const { lang, alternates = [] } = Astro.props as { lang?: 'da' | 'en'; alternates?: { lang: 'da' | 'en'; path: string }[] };
// Sprogskiftet bor KUN her: findes siden på det andet sprog (sidens alternates), linkes der til den.
const andet = alternates.find((a) => a.lang !== (lang ?? 'da'));
const nav = lang === 'en' ? NAV_EN : NAV;
const home = lang === 'en' ? '/en' : '/';
const path = Astro.url.pathname.replace(/\/$/, '') || '/';
@@ -23,6 +25,10 @@ const isActive = (href: string) => (href === '/' || href === '/en' ? path === hr
</li>
))}
</ul>
{andet && (
<a href={andet.path} hreflang={andet.lang} lang={andet.lang}
class="mr-1 rounded-full border border-border px-2.5 py-0.5 text-sm text-muted transition-colors hover:border-accent hover:text-accent">{andet.lang === 'en' ? 'English' : 'Dansk'}</a>
)}
<button type="button" data-palette-open class="theme-toggle" title="Søg (⌘K / Ctrl K)" aria-label="Åbn søgning og kommandopalette">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<circle cx="11" cy="11" r="7" />
+5 -9
View File
@@ -21,9 +21,9 @@ const oversigt = en ? '/en/projects' : '/projekter';
const T = en
? { hjem: 'Home', projekter: 'Projects', sprog: 'Language', licens: 'Licence', koerer: 'Runs on',
kilde: 'Source on Gitea', bin: 'Prebuilt packages', skift: 'Dansk' }
kilde: 'Source on Gitea', bin: 'Prebuilt packages' }
: { hjem: 'Forside', projekter: 'Projekter', sprog: 'Sprog', licens: 'Licens', koerer: 'Kører på',
kilde: 'Kildekode på Gitea', bin: 'Færdigbyggede pakker', skift: 'English' };
kilde: 'Kildekode på Gitea', bin: 'Færdigbyggede pakker' };
const url = new URL(sti(d.lang), SITE.url).href;
const repo = `${SITE.giteaBase}/${SITE.giteaUser}/${d.repo}`;
@@ -37,7 +37,7 @@ const ld = softwareSourceCode({
lang: d.lang,
});
const crumbs = breadcrumb([
{ name: T.hjem, url: `${SITE.url}/` },
{ name: T.hjem, url: `${SITE.url}${en ? '/en' : '/'}` },
{ name: T.projekter, url: `${SITE.url}${oversigt}` },
{ name: d.title, url },
]);
@@ -47,16 +47,12 @@ const alternates = oversat
---
<Base title={d.title} description={d.description} type="article" lang={d.lang} {alternates}
publishedTime={published} modifiedTime={modified} tags={d.tags} jsonLd={[ld, crumbs]}>
<div class="flex items-center justify-between gap-4 text-sm text-muted">
<div class="text-sm text-muted">
<nav aria-label={en ? 'Breadcrumb' : 'Brødkrumme'}>
<a href="/" class="hover:text-accent">{T.hjem}</a>
<a href={en ? '/en' : '/'} class="hover:text-accent">{T.hjem}</a>
<span class="px-1.5 text-muted/60">/</span>
<a href={oversigt} class="hover:text-accent">{T.projekter}</a>
</nav>
{oversat && (
<a href={sti(oversat.data.lang)} hreflang={oversat.data.lang} lang={oversat.data.lang}
class="rounded-full border border-border px-2.5 py-0.5 hover:border-accent hover:text-accent">{T.skift}</a>
)}
</div>
<article class="mt-4">
<header class="border-b border-border pb-6">
+1 -1
View File
@@ -68,7 +68,7 @@ const { title, description, image, type, publishedTime, modifiedTime, tags, json
UDKAST, ikke udgivet. <a href="/udkast/" class="underline">Tilbage til godkendelse</a>
</div>
)}
<Header {lang} />
<Header {lang} {alternates} />
<main class="mx-auto w-full max-w-3xl flex-1 px-5 py-12">
<slot />
</main>
+1 -4
View File
@@ -4,10 +4,7 @@ import Chat from '../components/Chat.astro';
---
<Base title="Spørg mit CV" description="En lille AI-chat der svarer på spørgsmål om mig, min erfaring og mit homelab." noindex
alternates={[{ lang: 'da', path: '/chat' }, { lang: 'en', path: '/en/chat' }]}>
<div class="flex items-center justify-between gap-4">
<h1 class="text-4xl font-bold tracking-tight">Spørg mit CV</h1>
<a href="/en/chat" hreflang="en" lang="en" class="rounded-full border border-border px-2.5 py-0.5 text-sm text-muted hover:border-accent hover:text-accent">English</a>
</div>
<h1 class="text-4xl font-bold tracking-tight">Spørg mit CV</h1>
<p class="mt-4 max-w-2xl text-muted">
En lille chat med <strong class="text-text">Claude</strong> fra Anthropic, der har læst mit CV og denne
side og svarer på spørgsmål om mig.. fx <em>“hvad har Asger lavet med Peppol?”</em> eller
+1 -4
View File
@@ -59,10 +59,7 @@ const sprog = ['Dansk (modersmål)', 'Engelsk (flydende i tale og skrift)'];
---
<Base title="CV" description="Asger Weirsøe, datalog og Technical Solution Architect. Erfaring, uddannelse og publikationer."
alternates={[{ lang: 'da', path: '/cv' }, { lang: 'en', path: '/en/cv' }]}>
<div class="flex items-center justify-between gap-4">
<h1 class="text-4xl font-bold tracking-tight">CV</h1>
<a href="/en/cv" hreflang="en" lang="en" class="rounded-full border border-border px-2.5 py-0.5 text-sm text-muted hover:border-accent hover:text-accent">English</a>
</div>
<h1 class="text-4xl font-bold tracking-tight">CV</h1>
<div class="mt-3 flex flex-wrap gap-x-4 gap-y-1 text-sm text-muted">
<span>{SITE.location}</span>
<a class="text-accent hover:underline" href={`mailto:${SITE.email}`}>{SITE.email}</a>
+1 -4
View File
@@ -4,10 +4,7 @@ import Chat from '../../components/Chat.astro';
---
<Base title="Ask my CV" description="A small chat with Claude that answers questions about me, my experience and my homelab." noindex
lang="en" alternates={[{ lang: 'da', path: '/chat' }, { lang: 'en', path: '/en/chat' }]}>
<div class="flex items-center justify-between gap-4">
<h1 class="text-4xl font-bold tracking-tight">Ask my CV</h1>
<a href="/chat" hreflang="da" lang="da" class="rounded-full border border-border px-2.5 py-0.5 text-sm text-muted hover:border-accent hover:text-accent">Dansk</a>
</div>
<h1 class="text-4xl font-bold tracking-tight">Ask my CV</h1>
<p class="mt-4 max-w-2xl text-muted">
A small chat with <strong class="text-text">Claude</strong> from Anthropic. It has read my CV and this
site and answers questions about me.. try <em>“what incident response experience does Asger have?”</em>
+1 -4
View File
@@ -40,10 +40,7 @@ const skills = [
---
<Base title="CV" description="Asger Weirsøe, computer scientist and Technical Solution Architect. Incident response, ISO/IEC 27001 compliance and national e-invoicing infrastructure."
lang="en" alternates={[{ lang: 'da', path: '/cv' }, { lang: 'en', path: '/en/cv' }]}>
<div class="flex items-center justify-between gap-4">
<h1 class="text-4xl font-bold tracking-tight">CV</h1>
<a href="/cv" hreflang="da" lang="da" class="rounded-full border border-border px-2.5 py-0.5 text-sm text-muted hover:border-accent hover:text-accent">Dansk</a>
</div>
<h1 class="text-4xl font-bold tracking-tight">CV</h1>
<div class="mt-3 flex flex-wrap gap-x-4 gap-y-1 text-sm text-muted">
<span>Aalborg, Denmark</span>
<a class="text-accent hover:underline" href={`mailto:${SITE.email}`}>{SITE.email}</a>
+2 -5
View File
@@ -32,10 +32,7 @@ const faqs = [
lang="en" alternates={[{ lang: 'da', path: '/' }, { lang: 'en', path: '/en' }]}>
<section class="grid items-center gap-8 py-6 sm:grid-cols-[1fr_auto]">
<div>
<div class="flex items-center justify-between gap-4">
<p class="font-medium text-accent">Hi, I am</p>
<a href="/" hreflang="da" lang="da" class="rounded-full border border-border px-2.5 py-0.5 text-sm text-muted hover:border-accent hover:text-accent">Dansk</a>
</div>
<p class="font-medium text-accent">Hi, I am</p>
<h1 class="mt-1 text-5xl font-bold tracking-tight sm:text-6xl">Asger Weirsøe</h1>
<p class="mt-3 text-xl font-semibold text-accent sm:text-2xl">Computer scientist &amp; Technical Solution Architect</p>
<p class="mt-5 max-w-xl text-lg text-muted">
@@ -98,6 +95,6 @@ const faqs = [
</details>
))}
</div>
<p class="mt-6 text-sm text-muted">The blog and the e-invoicing tools are in Danish. Everything on this page is also available <a href="/" hreflang="da" class="text-accent hover:underline">in Danish</a>.</p>
<p class="mt-6 text-sm text-muted">The blog and the e-invoicing tools are in Danish.</p>
</section>
</Base>
+1 -4
View File
@@ -13,10 +13,7 @@ const ld = collectionPage({
---
<Base title="Projects" description="Tools I write and publish on the AUR, Homebrew and Scoop." lang="en"
alternates={[{ lang: 'da', path: '/projekter' }, { lang: 'en', path: '/en/projects' }]} jsonLd={[ld]}>
<div class="flex items-center justify-between gap-4">
<h1 class="text-4xl font-bold tracking-tight">Projects</h1>
<a href="/projekter" hreflang="da" lang="da" class="rounded-full border border-border px-2.5 py-0.5 text-sm text-muted hover:border-accent hover:text-accent">Dansk</a>
</div>
<h1 class="text-4xl font-bold tracking-tight">Projects</h1>
<p class="mt-3 text-muted">Tools I maintain and publish as packages. Everything else lives on my <a class="text-accent hover:underline" href={`${SITE.giteaBase}/${SITE.giteaUser}`}>Gitea</a>.</p>
<div class="mt-8 grid gap-4 sm:grid-cols-2">
{sider.map((p) => (
-1
View File
@@ -59,7 +59,6 @@ const jsonLd = [profilePage, faqPage(faqs)];
<a href="/cv" class="rounded-xl bg-accent px-5 py-2.5 font-medium text-bg transition-transform hover:-translate-y-0.5">Se mit CV</a>
<a href="/projekter" class="rounded-xl border border-border px-5 py-2.5 font-medium transition-colors hover:border-accent">Projekter</a>
<a href="/blog" class="rounded-xl border border-border px-5 py-2.5 font-medium transition-colors hover:border-accent">Blog</a>
<a href="/en" hreflang="en" lang="en" class="rounded-xl border border-border px-5 py-2.5 font-medium transition-colors hover:border-accent">English</a>
</div>
</div>
<Image