Skip to content

fix(theme): keep stored preference across hard refresh - #951

Merged
Nanafancy merged 1 commit into
Ignition-World:mainfrom
moon-code12:fix/theme-hard-refresh
Oct 21, 2026
Merged

Nanafancy merged 1 commit into
Ignition-World:mainfrom
moon-code12:fix/theme-hard-refresh

Conversation

@moon-code12

@moon-code12 moon-code12 commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Pins the hard-refresh theme behavior and removes the last way the stored preference can drift.

  • Exported THEME_STORAGE_KEY / CONTRAST_STORAGE_KEY as the single source of truth.
  • getStoredTheme, storeTheme, getStoredContrast, storeContrast, and the blocking themeBootstrapScript now all use those constants instead of repeating string literals.
  • Added tests/theme-hard-refresh.test.tsx, which runs the real <head> bootstrap script, drops the module store to simulate a full reload, then mounts ThemeToggle:
    • stored light + OS dark -> stays light,
    • stored dark + OS light -> stays dark,
    • system -> follows the OS,
    • bootstrap and persistence helpers agree on the storage keys.

This also documents and protects the earlier #627 fix (blocking first-paint script + one shared store), which is what prevents the OS scheme from overwriting an explicit choice after refresh.

Closes #865

Closes #843

Root cause / behavior

The toggle writes an explicit mode to localStorage; the blocking script and the React store must read the same key before the first paint. A key mismatch (or a missing pre-paint read) leaves the page on the system scheme until hydration, and any system consumer can then re-apply it. The bootstrap script and the store now share exported constants, and the regression test runs the actual bootstrap script rather than a reimplementation.

No user-facing behavior is intended to change: the key names are still theme and contrast; only their definition is centralized.

Tests

cd ignition-pay-frontend
npx vitest run tests/theme-hard-refresh.test.tsx tests/theme-persistence.test.tsx tests/use-theme.test.tsx
Test Files  3 passed (3)
Tests       34 passed (34)

Breakdown:

  • theme-hard-refresh.test.tsx: 4 new tests
  • theme-persistence.test.tsx: 18 passed
  • use-theme.test.tsx: 12 passed

Lint:

npx eslint lib/theme.ts tests/theme-hard-refresh.test.tsx

Passed with no errors/warnings.

Type-check: npx tsc --noEmit produced no errors for the changed files.

@drips-wave

drips-wave Bot commented Oct 20, 2026

Copy link
Copy Markdown

@moon-code12 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@Nanafancy
Nanafancy merged commit 8549bb5 into Ignition-World:main Oct 21, 2026
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.

[WEB-008] Theme toggle reverts to system preference on hard refresh [CONTRACT-031] No emergency pause integration across the payment contracts

2 participants