Initial commit: Astro 6 static blog site
All checks were successful
Deploy / deploy (push) Successful in 49s
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>
This commit is contained in:
commit
5bb63bacf5
95 changed files with 12199 additions and 0 deletions
57
src/layouts/BaseLayout.astro
Normal file
57
src/layouts/BaseLayout.astro
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
---
|
||||
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>
|
||||
Loading…
Add table
Add a link
Reference in a new issue