adrian-altner.de/src/layouts/BaseLayout.astro
Adrian Altner 5bb63bacf5
All checks were successful
Deploy / deploy (push) Successful in 49s
Initial commit: Astro 6 static blog site
- German (default) and English i18n support
- Categories and tags
- Blog posts with hero images
- Dark/light theme switcher
- View Transitions removed to fix reload ghost images
- Webmentions integration
- RSS feeds per locale

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-04-22 10:55:29 +02:00

57 lines
1.6 KiB
Text

---
import type { ImageMetadata } from 'astro';
import type { CollectionEntry } from 'astro:content';
import BaseHead from '~/components/BaseHead.astro';
import Footer from '~/components/Footer.astro';
import Header from '~/components/Header.astro';
import { DEFAULT_LOCALE, type Locale } from '~/consts';
import { getLocaleFromUrl } from '~/i18n/ui';
interface Props {
title: string;
description: string;
locale?: Locale;
image?: ImageMetadata;
/** Current content entry, used for the language switcher's translation lookup. */
entry?: CollectionEntry<'posts' | 'categories'>;
/** Optional extra class on `<body>` for per-page styling hooks. */
bodyClass?: string;
}
const {
title,
description,
image,
entry,
bodyClass,
locale = getLocaleFromUrl(Astro.url) ?? DEFAULT_LOCALE,
} = Astro.props;
---
<!doctype html>
<html lang={locale}>
<head>
<BaseHead title={title} description={description} image={image} locale={locale} />
<script is:inline>
(() => {
const root = document.documentElement;
const stored = localStorage.getItem('theme');
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
const theme = stored === 'dark' || stored === 'light' ? stored : prefersDark ? 'dark' : 'light';
root.dataset.theme = theme;
// Enable theme transitions after initial render
requestAnimationFrame(() =>
requestAnimationFrame(() => root.setAttribute('data-theme-ready', '')),
);
})();
</script>
<slot name="head" />
</head>
<body class={bodyClass}>
<Header locale={locale} entry={entry} />
<main>
<slot />
</main>
<Footer locale={locale} />
</body>
</html>