Skip to content

Commit d83e9d2

Browse files
committed
🤖 fix: apply theme synchronously to document before React renders
The key insight: React's useLayoutEffect runs AFTER initial render, but Chromatic needs the theme applied BEFORE rendering starts to avoid flashing and capture correct snapshots. Solution: Apply theme to document.documentElement synchronously in the decorator, before returning the ThemeProvider. This ensures: - Light mode stories render in light theme immediately - Dark mode stories render in dark theme immediately - No flash of wrong theme during Chromatic snapshots Credit: simpler synchronous approach beats async React lifecycle.
1 parent 0780973 commit d83e9d2

File tree

1 file changed

+7
-6
lines changed

1 file changed

+7
-6
lines changed

.storybook/preview.tsx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,15 @@ const preview: Preview = {
2020
},
2121
decorators: [
2222
(Story, context) => {
23-
// Chromatic modes don't set context.globals during local development
24-
// They only work during Chromatic's CI snapshot process
25-
// For local development, globals.theme can be set via the toolbar
2623
const mode = context.globals.theme as ThemeMode | undefined;
2724

28-
// When no explicit mode is set (locally or via toolbar), don't force a theme
29-
// Let ThemeProvider use its default behavior (system preference / localStorage)
30-
// When Chromatic runs with modes, it will set globals.theme appropriately
25+
// Apply theme synchronously to document BEFORE React renders
26+
// This ensures Chromatic snapshots capture the correct theme without flashing
27+
if (mode && typeof document !== "undefined") {
28+
document.documentElement.dataset.theme = mode;
29+
document.documentElement.style.colorScheme = mode;
30+
}
31+
3132
return (
3233
<ThemeProvider forcedTheme={mode}>
3334
<Story />

0 commit comments

Comments
 (0)