Persist theme before hydration

This commit is contained in:
wuyang6
2026-06-12 19:58:16 +08:00
parent 4a268902bf
commit 611284b27a
3 changed files with 24 additions and 3 deletions
+7 -3
View File
@@ -26,14 +26,13 @@ export function ClawThemeSwitcher() {
const ActiveIcon = activeOption.icon; const ActiveIcon = activeOption.icon;
useEffect(() => { useEffect(() => {
const stored = window.localStorage.getItem(THEME_STORAGE_KEY); const initialMode = readStoredThemeMode();
const initialMode = isThemeMode(stored) ? stored : "system";
setMode(initialMode); setMode(initialMode);
applyTheme(initialMode); applyTheme(initialMode);
const media = window.matchMedia("(prefers-color-scheme: dark)"); const media = window.matchMedia("(prefers-color-scheme: dark)");
const onChange = () => { const onChange = () => {
if (window.localStorage.getItem(THEME_STORAGE_KEY) === "system") { if (readStoredThemeMode() === "system") {
applyTheme("system"); applyTheme("system");
} }
}; };
@@ -97,3 +96,8 @@ function applyTheme(mode: ThemeMode) {
function isThemeMode(value: string | null): value is ThemeMode { function isThemeMode(value: string | null): value is ThemeMode {
return value === "light" || value === "dark" || value === "system"; return value === "light" || value === "dark" || value === "system";
} }
function readStoredThemeMode(): ThemeMode {
const stored = window.localStorage.getItem(THEME_STORAGE_KEY);
return isThemeMode(stored) ? stored : "system";
}
+3
View File
@@ -25,6 +25,9 @@ export default function RootLayout({
}>) { }>) {
return ( return (
<html lang="zh-CN" suppressHydrationWarning> <html lang="zh-CN" suppressHydrationWarning>
<head>
<script src="/theme-init.js" />
</head>
<body <body
className={`${geistSans.variable} ${geistMono.variable} antialiased`} className={`${geistSans.variable} ${geistMono.variable} antialiased`}
> >
+14
View File
@@ -0,0 +1,14 @@
(() => {
try {
const stored = window.localStorage.getItem("claw.theme");
const mode =
stored === "light" || stored === "dark" || stored === "system"
? stored
: "system";
const prefersDark = window.matchMedia(
"(prefers-color-scheme: dark)",
).matches;
const shouldUseDark = mode === "dark" || (mode === "system" && prefersDark);
document.documentElement.classList.toggle("dark", shouldUseDark);
} catch (_) {}
})();