From 8ebfbabcc06674c4a9897dfa7bb53e3596d2a480 Mon Sep 17 00:00:00 2001 From: snowopsdev <6538071+snowopsdev@users.noreply.github.com> Date: Sat, 28 Feb 2026 12:00:21 -0500 Subject: [PATCH] fix: prevent theme switcher from overwriting saved theme on mount Wait for component to mount before attempting to write the current theme state to localStorage. This prevents the initial 'dracula' state from clobbering the user's saved preference before the initial read effect can update the state. --- components/theme-switcher.tsx | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/components/theme-switcher.tsx b/components/theme-switcher.tsx index d270d96..a8f4f36 100644 --- a/components/theme-switcher.tsx +++ b/components/theme-switcher.tsx @@ -32,21 +32,28 @@ interface ThemeSwitcherProps { */ export function ThemeSwitcher({ className = '' }: ThemeSwitcherProps) { const [theme, setTheme] = useState('dracula') + const [mounted, setMounted] = useState(false) const validThemeIds = useMemo(() => new Set(THEME_OPTIONS.map((o) => o.id)), []) useEffect(() => { + setMounted(true) const saved = localStorage.getItem('terminal-theme') const attr = document.documentElement.getAttribute('data-theme') const initial = [saved, attr].find( (v): v is ThemeId => !!v && validThemeIds.has(v as ThemeId), ) - if (initial) setTheme(initial) + if (initial) { + setTheme(initial) + // Apply immediately to avoid flash if state update takes a tick + document.documentElement.setAttribute('data-theme', initial) + } }, [validThemeIds]) useEffect(() => { + if (!mounted) return document.documentElement.setAttribute('data-theme', theme) localStorage.setItem('terminal-theme', theme) - }, [theme]) + }, [theme, mounted]) return (