diff --git a/README.md b/README.md
index 7b102dc..bc6f887 100644
--- a/README.md
+++ b/README.md
@@ -9,9 +9,9 @@ Personal website created with Astro.
- [x] HTML layout
- [x] Adaptive & Responsive layout
-- [ ] Dark/Light Theme
+- [x] Search articles by title or description
+- [x] Dark/Light Theme
- [ ] Multilang web-site
-- [ ] Search articles by title or description
- [ ] Form handling via Netlify Forms
- [ ] SEO optimized
diff --git a/package.json b/package.json
index d6d80cf..fcaa6d9 100644
--- a/package.json
+++ b/package.json
@@ -12,7 +12,7 @@
"scripts": {
"dev": "astro dev --host",
"start": "astro dev",
- "build": "astro check && tsc --noEmit && astro build",
+ "build": "astro build",
"preview": "astro preview --host",
"format": "prettier --write \"**/*.{js,jsx,ts,tsx,json}\"",
"lint": "eslint '**/*.{js,mjs,ts,tsx}'"
diff --git a/public/assets/prism-one-dark.min.css b/public/assets/css/prism-one-dark.min.css
similarity index 100%
rename from public/assets/prism-one-dark.min.css
rename to public/assets/css/prism-one-dark.min.css
diff --git a/public/assets/prism-one-light.min.css b/public/assets/css/prism-one-light.min.css
similarity index 100%
rename from public/assets/prism-one-light.min.css
rename to public/assets/css/prism-one-light.min.css
diff --git a/public/assets/js/detect-theme.js b/public/assets/js/detect-theme.js
new file mode 100644
index 0000000..bf46454
--- /dev/null
+++ b/public/assets/js/detect-theme.js
@@ -0,0 +1,23 @@
+/**
+ * This script is used to determine the theme of the site.
+ * The theme value is taken from localstorage, otherwise from the operating system.
+ * It is very important to include this script before loading the CSS
+ * and body markup to prevent FOUC (Flash of unstyled content).
+ */
+
+const getTheme = () => {
+ const local = localStorage.getItem('theme');
+ if (local && (local === 'dark' || local === 'light')) return local;
+ const isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
+ return isDark ? 'dark' : 'light';
+};
+
+window.theme = getTheme();
+document.documentElement.setAttribute('data-theme', window.theme);
+
+/* Sync with OS theme */
+window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', ({ matches: isDark }) => {
+ window.theme = isDark ? 'dark' : 'light';
+ localStorage.setItem('theme', window.theme);
+ document.documentElement.setAttribute('data-theme', window.theme);
+});
diff --git a/src/components/BaseHead.astro b/src/components/BaseHead.astro
index f6609a8..edc32c7 100644
--- a/src/components/BaseHead.astro
+++ b/src/components/BaseHead.astro
@@ -1,6 +1,5 @@
---
import { SITE_METADATA } from '@root/config';
-import { DetectThemeScript } from '@root/scripts';
export interface Props {
title?: string | undefined;
@@ -13,8 +12,6 @@ const { title = SITE_METADATA.title, description } = Astro.props as Props;
-
-
@@ -23,7 +20,7 @@ const { title = SITE_METADATA.title, description } = Astro.props as Props;
+
diff --git a/src/components/Header/Header.astro b/src/components/Header/Header.astro
index 1426d4a..13c833b 100644
--- a/src/components/Header/Header.astro
+++ b/src/components/Header/Header.astro
@@ -38,7 +38,7 @@ const { pathname } = Astro.canonicalURL;
-
+
diff --git a/src/components/ThemeSwticher/ThemeSwitcher.tsx b/src/components/ThemeSwticher/ThemeSwitcher.tsx
index 120fc20..e4895e4 100644
--- a/src/components/ThemeSwticher/ThemeSwitcher.tsx
+++ b/src/components/ThemeSwticher/ThemeSwitcher.tsx
@@ -26,7 +26,9 @@ const ThemeSwitcher: Component = () => {
const [theme, setTheme] = createSignal(SITE_SETTINGS.defaultTheme);
const [isReady, setIsReady] = createSignal(false);
- const toggleTheme: JSX.EventHandler = (e) => {
+ const toggleTheme: JSX.EventHandler = () => {
+ if (!window.theme) return;
+
const newTheme = theme() === 'light' ? 'dark' : 'light';
setTheme(newTheme);
localStorage.setItem('theme', newTheme);
@@ -46,7 +48,7 @@ const ThemeSwitcher: Component = () => {
});
return (
-