mirror of
https://github.com/ChenQihan666/MyBlog-Next.git
synced 2026-08-14 11:29:33 +08:00
e0506cb41e
* feat: toggle .dark class on theme change * feat: add callouts with rehype-callouts plugin * docs: update blog posts with callouts
128 lines
3.9 KiB
Plaintext
128 lines
3.9 KiB
Plaintext
---
|
|
import { Font } from "astro:assets";
|
|
import { ClientRouter } from "astro:transitions";
|
|
import { getRelativeLocaleUrl } from "astro:i18n";
|
|
import { resolveDefaultOgImagePath } from "@/utils/resolveDefaultOgImagePath";
|
|
import { getAssetPath } from "@/utils/withBase";
|
|
import config from "@/config";
|
|
import "@/styles/global.css";
|
|
|
|
type Props = {
|
|
title?: string;
|
|
description?: string;
|
|
ogImage?: string;
|
|
canonicalURL?: string;
|
|
};
|
|
|
|
const { site } = config;
|
|
|
|
const {
|
|
title = site.title,
|
|
description = site.description,
|
|
ogImage = resolveDefaultOgImagePath(config),
|
|
canonicalURL = new URL(Astro.url.pathname, Astro.site).href,
|
|
} = Astro.props;
|
|
|
|
const socialImageURL = new URL(ogImage, Astro.site ?? Astro.url);
|
|
const rssHref = getRelativeLocaleUrl(
|
|
Astro.currentLocale ?? config.site.lang,
|
|
"rss.xml"
|
|
);
|
|
---
|
|
|
|
<!doctype html>
|
|
<html
|
|
dir={site.dir ?? "ltr"}
|
|
lang={Astro.currentLocale ?? site.lang}
|
|
class="overflow-y-scroll scroll-smooth"
|
|
>
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
<link rel="icon" type="image/svg+xml" href={getAssetPath("favicon.svg")} />
|
|
<link rel="icon" href={getAssetPath("favicon.ico")} />
|
|
<link rel="canonical" href={canonicalURL} />
|
|
<meta name="generator" content={Astro.generator} />
|
|
|
|
<!-- Font -->
|
|
<Font
|
|
cssVariable="--font-google-sans-code"
|
|
preload={[{ subset: "latin", weight: 400, style: "normal" }]}
|
|
/>
|
|
|
|
<!-- Primary meta -->
|
|
<title>{title}</title>
|
|
<meta name="title" content={title} />
|
|
<meta name="description" content={description} />
|
|
<meta name="author" content={site.author} />
|
|
<link rel="sitemap" href={getAssetPath("sitemap-index.xml")} />
|
|
|
|
<!-- Open Graph -->
|
|
<meta property="og:type" content="website" />
|
|
<meta property="og:site_name" content={site.title} />
|
|
<meta property="og:title" content={title} />
|
|
<meta property="og:description" content={description} />
|
|
<meta property="og:url" content={canonicalURL} />
|
|
<meta property="og:image" content={socialImageURL} />
|
|
|
|
<!-- Twitter / X -->
|
|
<meta property="twitter:card" content="summary_large_image" />
|
|
<meta property="twitter:url" content={canonicalURL} />
|
|
<meta property="twitter:title" content={title} />
|
|
<meta property="twitter:description" content={description} />
|
|
<meta property="twitter:image" content={socialImageURL} />
|
|
|
|
<!-- RSS autodiscovery -->
|
|
<link
|
|
rel="alternate"
|
|
type="application/rss+xml"
|
|
title={site.title}
|
|
href={new URL(rssHref, Astro.site)}
|
|
/>
|
|
|
|
<!-- Filled at runtime by theme.ts to match the current background colour -->
|
|
<meta name="theme-color" content="" />
|
|
|
|
<!-- Extra head content injected by child layouts (e.g. JSON-LD, article meta) -->
|
|
<slot name="head" />
|
|
|
|
{
|
|
site.googleVerification && (
|
|
<meta
|
|
name="google-site-verification"
|
|
content={site.googleVerification}
|
|
/>
|
|
)
|
|
}
|
|
|
|
<!--
|
|
Inline FOUC-prevention script: sets data-theme on <html> before
|
|
the browser paints. Runs synchronously, no defer/async.
|
|
-->
|
|
<script is:inline>
|
|
(function () {
|
|
const stored = localStorage.getItem("theme");
|
|
const prefersDark = window.matchMedia(
|
|
"(prefers-color-scheme: dark)"
|
|
).matches;
|
|
const theme = stored ?? (prefersDark ? "dark" : "light");
|
|
const root = document.firstElementChild;
|
|
root?.setAttribute("data-theme", theme);
|
|
root?.classList.toggle("dark", theme === "dark");
|
|
// Expose value so theme.ts can skip re-detection.
|
|
window.__theme = { value: theme };
|
|
})();
|
|
</script>
|
|
|
|
<ClientRouter />
|
|
</head>
|
|
<body
|
|
class="bg-background font-app text-foreground selection:bg-accent/75 selection:text-accent-foreground flex min-h-svh flex-col"
|
|
>
|
|
<slot />
|
|
<script>
|
|
import "@/scripts/theme";
|
|
</script>
|
|
</body>
|
|
</html>
|