Skip to content

fix(theme-toggle): sync theme across tabs on storage event#11

Open
yyyr-p wants to merge 1 commit into
dimthink:mainfrom
yyyr-p:fix/theme-cross-tab-sync
Open

fix(theme-toggle): sync theme across tabs on storage event#11
yyyr-p wants to merge 1 commit into
dimthink:mainfrom
yyyr-p:fix/theme-cross-tab-sync

Conversation

@yyyr-p

@yyyr-p yyyr-p commented Jul 20, 2026

Copy link
Copy Markdown

Summary

ThemeToggle's storage event handler previously just called onStoreChange, which made useSyncExternalStore re-read the DOM. But the DOM was never modified by another tab — a storage event means a peer tab wrote to localStorage, while this tab's DOM state was unchanged, so cross-tab theme switches were silently dropped.

Fix: filter storage events by THEME_STORAGE_KEY, parse the target theme from event.newValue, call applyTheme to sync this tab's dataset.theme / style.colorScheme to that value, then trigger onStoreChange so useSyncExternalStore re-renders. Unknown or missing newValue is ignored; events for other storage keys are untouched; removeEventListener uses the same stable handler reference so no listener leaks.

Admin pages do not render ThemeToggle (SiteHeader is not mounted under src/app/admin/), so this handler never fires in an admin tab and does not conflict with the initial-paint script's forced-light policy on `/admin`.

Test plan

  • `npm run typecheck` passes
  • `npm run lint` passes (1 pre-existing unrelated warning)
  • `npm test` passes
  • `npm run build` passes
  • Manual: open two non-admin tabs, toggle theme in one, other tab mirrors immediately (both dark→light and light→dark)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant