From 611284b27acad9af5a36e78e4b6dc134e70497de Mon Sep 17 00:00:00 2001 From: wuyang6 Date: Fri, 12 Jun 2026 19:58:16 +0800 Subject: [PATCH] Persist theme before hydration --- frontend/app/app/claw-theme-switcher.tsx | 10 +++++++--- frontend/app/app/layout.tsx | 3 +++ frontend/app/public/theme-init.js | 14 ++++++++++++++ 3 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 frontend/app/public/theme-init.js diff --git a/frontend/app/app/claw-theme-switcher.tsx b/frontend/app/app/claw-theme-switcher.tsx index 6e25412..7c7dd2d 100644 --- a/frontend/app/app/claw-theme-switcher.tsx +++ b/frontend/app/app/claw-theme-switcher.tsx @@ -26,14 +26,13 @@ export function ClawThemeSwitcher() { const ActiveIcon = activeOption.icon; useEffect(() => { - const stored = window.localStorage.getItem(THEME_STORAGE_KEY); - const initialMode = isThemeMode(stored) ? stored : "system"; + const initialMode = readStoredThemeMode(); setMode(initialMode); applyTheme(initialMode); const media = window.matchMedia("(prefers-color-scheme: dark)"); const onChange = () => { - if (window.localStorage.getItem(THEME_STORAGE_KEY) === "system") { + if (readStoredThemeMode() === "system") { applyTheme("system"); } }; @@ -97,3 +96,8 @@ function applyTheme(mode: ThemeMode) { function isThemeMode(value: string | null): value is ThemeMode { return value === "light" || value === "dark" || value === "system"; } + +function readStoredThemeMode(): ThemeMode { + const stored = window.localStorage.getItem(THEME_STORAGE_KEY); + return isThemeMode(stored) ? stored : "system"; +} diff --git a/frontend/app/app/layout.tsx b/frontend/app/app/layout.tsx index 7a0c706..0f6d4ee 100644 --- a/frontend/app/app/layout.tsx +++ b/frontend/app/app/layout.tsx @@ -25,6 +25,9 @@ export default function RootLayout({ }>) { return ( + +