Improve theming to prevent the flash of incorrect color scheme (FOUC)
Description
Theme is applied entirely client-side: src/components/ThemeToggle.tsx toggles the dark class on documentElement inside a useEffect, so a user who chose dark mode sees a white flash on every navigation until hydration runs. src/app/layout.tsx hard-codes <html lang="en"> with no early theme application and the CSS in src/app/globals.css relies solely on prefers-color-scheme. This issue applies the stored theme before first paint.
Requirements and context
- Repository scope:
Agentpay-Org/Agentpay-frontend only.
- Inject a tiny blocking inline script in
src/app/layout.tsx <head> that reads agentpay.theme from localStorage (key matches src/lib/theme.ts) and sets the dark class synchronously before the body renders.
- Ensure the
system setting still honours prefers-color-scheme and that the script is the single source of truth shared with src/lib/theme.ts (no key drift).
- Respect
prefers-reduced-motion where any theme-transition CSS is added.
Suggested execution
- Fork the repo and create a branch
git checkout -b a11y/a11y-21-theme-fouc
- Implement changes
- Write code in:
src/app/layout.tsx (inline pre-paint script) and reconcile src/lib/theme.ts.
- Write comprehensive tests in: create
src/lib/__tests__/theme.test.ts cases or a layout test asserting the storage key and class logic match.
- Add documentation: document the anti-FOUC approach in
README.md.
- Validate no hydration mismatch warning is produced.
- Test and commit
Test and commit
- Run
npm run lint, npm run typecheck, npm test, and npm run build.
- Cover edge cases: no stored theme (defaults to system), corrupt stored value, and SSR with
localStorage absent.
- Include the
npm test output and a note confirming no hydration warnings in npm run dev.
Example commit message
fix(a11y): apply stored theme before first paint to remove dark-mode flash
Guidelines
- Minimum 95 percent test coverage for the touched theme logic.
- Clear, reviewer-focused documentation.
- Timeframe: 96 hours.
Community & contribution rewards
- 💬 Join the AgentPay community on Discord for questions, reviews, and faster merges: https://discord.gg/eXvRKkgcv
- ⭐ This is a GrantFox OSS / Official Campaign task and may be rewarded. When your PR is merged you'll be prompted to rate the project — if this issue and the maintainers helped you ship, we'd be grateful for a 5-star rating. Clear questions in Discord and tidy, well-tested PRs are the fastest path to a merge and a reward.
Improve theming to prevent the flash of incorrect color scheme (FOUC)
Description
Theme is applied entirely client-side:
src/components/ThemeToggle.tsxtoggles thedarkclass ondocumentElementinside auseEffect, so a user who chose dark mode sees a white flash on every navigation until hydration runs.src/app/layout.tsxhard-codes<html lang="en">with no early theme application and the CSS insrc/app/globals.cssrelies solely onprefers-color-scheme. This issue applies the stored theme before first paint.Requirements and context
Agentpay-Org/Agentpay-frontendonly.src/app/layout.tsx<head>that readsagentpay.themefromlocalStorage(key matchessrc/lib/theme.ts) and sets thedarkclass synchronously before the body renders.systemsetting still honoursprefers-color-schemeand that the script is the single source of truth shared withsrc/lib/theme.ts(no key drift).prefers-reduced-motionwhere any theme-transition CSS is added.Suggested execution
git checkout -b a11y/a11y-21-theme-foucsrc/app/layout.tsx(inline pre-paint script) and reconcilesrc/lib/theme.ts.src/lib/__tests__/theme.test.tscases or a layout test asserting the storage key and class logic match.README.md.Test and commit
npm run lint,npm run typecheck,npm test, andnpm run build.localStorageabsent.npm testoutput and a note confirming no hydration warnings innpm run dev.Example commit message
fix(a11y): apply stored theme before first paint to remove dark-mode flashGuidelines
Community & contribution rewards