All checks were successful
Deploy / deploy (push) Successful in 49s
- 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>
57 lines
1.6 KiB
Text
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>
|