diff --git a/frontend/src/components/theme-provider.tsx b/frontend/src/components/theme-provider.tsx index a582b28..9d9d9d4 100644 --- a/frontend/src/components/theme-provider.tsx +++ b/frontend/src/components/theme-provider.tsx @@ -35,11 +35,17 @@ export function ThemeProvider({ ...props }: ThemeProviderProps) { const [theme, setTheme] = useState( - () => (localStorage.getItem(storageKey) as Theme) || defaultTheme, + () => + (typeof localStorage !== "undefined" + ? (localStorage.getItem(storageKey) as Theme) + : null) || defaultTheme, ) const getResolvedTheme = useCallback((theme: Theme): "dark" | "light" => { if (theme === "system") { + // Prerendered HTML has no preference to read; the pre-paint script in + // the document head resolves it before React ever hydrates. + if (typeof window === "undefined") return "light" return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"