Skip to content

Commit 9f224e6

Browse files
committed
Fix theme toggle functionality - ensure toggleTheme always works
- Remove empty function fallback that prevented toggle from working - Improve state synchronization on mount - Ensure DOM updates only happen after component is mounted
1 parent dcdc607 commit 9f224e6

1 file changed

Lines changed: 22 additions & 9 deletions

File tree

components/ThemeProvider.tsx

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,27 @@ export function ThemeProvider({ children }: { children: React.ReactNode }) {
4141

4242
useEffect(() => {
4343
setMounted(true);
44-
// Sync with the theme that was set by the inline script
45-
const currentTheme = document.documentElement.classList.contains('dark') ? 'dark' : 'light';
46-
setThemeState(currentTheme);
44+
// On mount, ensure DOM and state are in sync
45+
// The inline script should have already set the DOM class
46+
if (typeof window !== 'undefined') {
47+
const storedTheme = localStorage.getItem('theme') as Theme | null;
48+
const domHasDark = document.documentElement.classList.contains('dark');
49+
const domTheme = domHasDark ? 'dark' : 'light';
50+
51+
// Use stored theme if available, otherwise use what's in the DOM
52+
const actualTheme = storedTheme || domTheme;
53+
54+
// Update state to match what's actually in the DOM/localStorage
55+
// This ensures consistency after the inline script runs
56+
setThemeState((currentTheme) => {
57+
// Only update if there's a mismatch
58+
return actualTheme !== currentTheme ? actualTheme : currentTheme;
59+
});
60+
}
4761
}, []);
4862

4963
useEffect(() => {
50-
if (typeof window === 'undefined') return;
64+
if (typeof window === 'undefined' || !mounted) return;
5165

5266
const root = document.documentElement;
5367
if (theme === 'dark') {
@@ -56,7 +70,7 @@ export function ThemeProvider({ children }: { children: React.ReactNode }) {
5670
root.classList.remove('dark');
5771
}
5872
localStorage.setItem('theme', theme);
59-
}, [theme]);
73+
}, [theme, mounted]);
6074

6175
const toggleTheme = () => {
6276
setThemeState((prev) => (prev === 'light' ? 'dark' : 'light'));
@@ -66,10 +80,9 @@ export function ThemeProvider({ children }: { children: React.ReactNode }) {
6680
setThemeState(newTheme);
6781
};
6882

69-
// Always provide context, even during SSR
70-
const contextValue = mounted
71-
? { theme, toggleTheme, setTheme }
72-
: { theme, toggleTheme: () => {}, setTheme: () => {} };
83+
// Always provide working functions, even during SSR
84+
// The theme state will sync properly once mounted
85+
const contextValue = { theme, toggleTheme, setTheme };
7386

7487
return (
7588
<ThemeContext.Provider value={contextValue}>

0 commit comments

Comments
 (0)