Nextjs with SSR flashes themeless UI
See original GitHub issueDescription
When I have cookieStorageManagerSSR on (and do not have ColorModeScript), the first paint flashes a (mostly) unthemed skeleton.
Link to Reproduction
https://codesandbox.io/s/confident-wing-ztomgs?file=/Chakra.js:378-401
Steps to reproduce
- Open Codesandbox link
- Notice how ColorModeScript in _document is commented out[1]
- Notice how colorModeManager is set in Chakra.js
- Open Codesandbox preview to a new window
- Refresh the page and notice the first render is jarring. Toggle to dark mode, refresh the page and notice it’s even more jarring. Turn off Javascript (I use Quick Javascript Switcher chrome extension but you can probably do this from the dev tools) and notice how some elements have received the theme like the button text, but most of the page has not. In dark mode this is especially noticeable as you flash from black to white and then the DOM is updated with the CSS classes.
Bonus: 7. Comment back in ColorModeScript. Refresh and notice that it’s so much better! 8. But then toggle the theme and refresh your page. The cookie value was updated but the localStorage was not (confirmed by looking in Application Storage in the devtools). The server now expects one mode and the client expects another which causes a flash (black to white or white to black).
Chakra UI Version
2.2.1
Browser
Chrome 105
Operating System
- macOS
- Windows
- Linux
Additional Information
[1] ColorModeScript in _document is commented out – From the docs: “Also, if you use colorModeManager, you can avoid adding the <ColorModeScript /> to _document.js.” and also in this recent PR https://github.com/chakra-ui/chakra-ui/pull/6035/files#diff-2195e3eb593f2d293a26fbbb447b9efae1bf3b08202902799424c8f62872dff6R11-R12
Overall I would think that the cookie would take precedence over the value in localStorage especially since I’m explicitly passing cookieStorageManagerSSR
to the colorModeManager
. This can be extra tricky to debug because the localStorage value isn’t cleared out in an obvious way and Chakra still acknowledges it even after ColorModeScript is removed.
There’s really two problems at play here, both relating to Next.js and SSR:
- The SSR is lacking. Is it a bug? It’s very unpleasant especially in dark mode. I found this site that’s using Chakra and SSR, but there’s no flashing and when you turn off JS on the frontend, you can see the server responds with a DOM tree populated with classnames, so I think what’s happening now is a bug.
- Cookies vs local storage. LocalStorage takes priority and if you’re using both colorModeManager and ColorModeScript you’re going to have a bad time. You’ll have a worse time if you don’t use ColorModeScript at all though.
And a bonus^2!
3. When I manually changed ColorModeScript to dark mode, it never would change for me. I bet it was because light
was in my localStorage. So anyone else out there reading this, go to your dev tools > Application > Storage > Local Storage
and if you see the key/value there you can right click and delete it 😃
Issue Analytics
- State:
- Created a year ago
- Reactions:7
- Comments:8 (1 by maintainers)
Top GitHub Comments
I made substantial progress on this: https://codesandbox.io/s/priceless-night-6f0292?file=/pages/_document.js
__document.tsx
So notably here: I added
data-theme
andstyle={{ colorScheme }}
to Html andclassName="chakra-ui-{colorMode}"
to body.This actually works! (I don’t really care about colorMode system so I don’t know if that one works.) This is really fantastic and it actually works great!!
The only todo here would be improving documentation 😃 and exporting parseCookie so it doesn’t need to be copied in here.
@jca41
really? I didn’t notice any issue. See if you notice anything: https://checklist-remix.vercel.app/