diff --git a/src/components/theme-provider.tsx b/src/components/theme-provider.tsx index 76c7315f8..37b7465f5 100644 --- a/src/components/theme-provider.tsx +++ b/src/components/theme-provider.tsx @@ -35,6 +35,24 @@ function getThemeScript(storageKey: string, defaultTheme: Theme) { return `(function(){try{var t=localStorage.getItem(${key});if(t!=='light'&&t!=='dark'&&t!=='system'){t=${fallback}}var d=matchMedia('(prefers-color-scheme: dark)').matches;var r=t==='system'?(d?'dark':'light'):t;var e=document.documentElement;e.classList.add(r);e.style.colorScheme=r}catch(e){}})();`; } +type ThemeScriptProps = { + defaultTheme?: Theme; + storageKey?: string; +}; + +/** + * Inline script that resolves and applies the theme to `document.documentElement` + * before paint. It must render in `
` so it runs during HTML parsing, ahead + * of body hydration — otherwise its mutation of the root element races React's + * whole-document hydration and can surface as a #418 mismatch. + */ +export function ThemeScript({ + defaultTheme = "system", + storageKey = defaultThemeStorageKey, +}: ThemeScriptProps) { + return