src/layouts/Base.astro 1.9 K raw
1
---
2
import type { SiteMeta } from "@/data/siteMeta";
3
import BaseHead from "@/components/BaseHead";
4
import Header from "@/components/layout/Header";
5
import Footer from "@/components/layout/Footer";
6
import SkipLink from "@/components/SkipLink";
7
import siteConfig from "@/site-config";
8
import { GoogleAnalytics } from "astro-google-analytics"
9
10
interface Props {
11
	meta: SiteMeta;
12
}
13
14
const {
15
	meta: { title, description = siteConfig.description, ogImage, articleDate },
16
} = Astro.props;
17
---
18
19
<html lang={siteConfig.lang}>
20
	<head>
21
		<BaseHead title={title} description={description} ogImage={ogImage} articleDate={articleDate} /> <GoogleAnalytics id="G-QT67QEFLTG" /> <script define:vars={{ siteConfig }}> const root = document.documentElement;
22
			const colorThemeMetaTag = document.querySelector("meta[name='theme-color']");
23
24
			// get user preference of dark mode, 1st local storage, 2nd browser
25
			function getThemePreference() {
26
				if (typeof localStorage !== "undefined" && localStorage.getItem("theme")) {
27
					return localStorage.getItem("theme");
28
				}
29
				return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
30
			}
31
32
			const isDark = getThemePreference() === "dark";
33
34
			// watch document element class attribute and update user preference when it changes.
35
			const observer = new MutationObserver(() => {
36
				const rootIsDark = root.classList.contains("dark");
37
				// set the meta attribute
38
				colorThemeMetaTag.setAttribute(
39
					"content",
40
					siteConfig[rootIsDark ? "themeColorDark" : "themeColorLight"]
41
				);
42
				// store user preference
43
				if (typeof localStorage !== "undefined") {
44
					localStorage.setItem("theme", rootIsDark ? "dark" : "light");
45
				}
46
			});
47
			observer.observe(root, { attributeFilter: ["class"] });
48
49
			// initailse root class attribute
50
			root.classList.toggle("dark", isDark);
51
		</script>
52
	</head>
53
	<body>
54
		<SkipLink />
55
		<Header />
56
		<main id="main" class="flex-1">
57
			<slot />
58
		</main>
59
		<Footer />
60
	</body>
61
</html>