question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

SSR broken with dynamic, cookie-based theme (dark mode doesn't work)

See original GitHub issue

Hello!

I discovered an issue in my app (Next JS with Material UI v5 and “next-dark-mode”), and hoped you might be able to help 😃

TLDR:

Determining the theme based on a cookie seems to generate two sets of stylesheets on the server. This breaks the theming on the client.

Code sandbox:

https://codesandbox.io/s/vigorous-noether-5xxr6

GIF:

ezgif-6-d2e3947a0aac

Steps to reproduce:

  1. Open up the project from the CodeSandbox linked above and let the homepage load.
  2. Refresh the page. You should see nothing out of the ordinary (I assume because there’s no theme cookie yet).
  3. Now click the “switch theme” button in the middle. The theme should switch correctly to light / dark.
  4. Now refresh the page —> ??? The background should be the wrong color!
  5. Click the button to switch themes and you should see that the “new theme” is correct, and looks a lot like the old broken theme.
  6. Refresh the page again, and you should see the same bug with the opposite color as well — parts of the page are using the correct colors, while other parts are not.

Switching themes twice “fixes” the theme to have the right colors, but only until the next page visit / next refresh.

It looks like the cookie seems to work incorrectly when theme styles are generated on the server side.


Details:

After upgrading to MUI 5 last weekend, I noticed that the footer of my app always had the links in the wrong color for some reason. So I tried to investigate.

I saw that I seemed to be getting two sets of styles on the client, as can be seen in the screenshot below:

Screenshot 2021-10-23 at 9 33 10 AM

These conflicted with each other in somewhat unpredictable ways. In my case the result was that 99% of the app seemed to look fine, except for the footer. In the CodeSandbox above, it seemed to affect the body background color as well.

I’m using the “next-dark-mode” library, which uses a cookie to store the user’s dark mode preference. This cookie is supposed to let my Theme component determine the right theme during server-side rendering. In my app all pages are currently server-side rendered (i.e. no static pages), but the theming bug is still present.

In the gif above you can see that the theme seems to be generated correctly when the user clicks a button to switch modes, but breaks when the user comes back to the page (e.g. after refreshing).

If I remove getInitialProps from my _document.tsx file, then this bug does not occur.

.

I’m hoping that this is just a user-error on my part. However, I didn’t have this issue in MUI 4 (back then I used ServerStyleSheets from MUI styles and merged them in getInitialProps in _document.tsx in much the same way as now.)

To be honest I have no idea what’s really happening under the hood here. I’m a bit new to Next JS and certainly very new to emotion (e.g. I have no idea whatsoever how it’s caching works). But before I spend many hours debugging and diving down the info rabbit hole of how server-side rendered styles work, I thought I’d try my luck asking for help here first 😄


While I’m here, allow me to say that I really love this library. It made my MUI 5 migration very smooth and easy, I have no idea how many hours it would’ve taken if I had to refactor everything to styled components.

Also, I really love how the results of functions return objects. It makes it so easy to just autocomplete the results of everything, so I never make typos and I never have to worry about naming things. And of course being a big TS fan I love that everything could be kept type-safe 😄 So yeah, even if I need to take this issue to another library, just wanted to say thanks a lot for your hard work! 😄

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:2
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
garronejcommented, Oct 24, 2021

@Deckstar It’s fixed in v2.

Updated sandbox

Thank you for reporting, it was a big issue that needed to be addressed.

Best

1reaction
garronejcommented, Oct 23, 2021

Found the bug. I am to blame. Fixing.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Material ui dark mode reset when page refreshing?
Load the theme mode reading from the browser preference if there's no storage value, using the Material UI useMediaQuery hook.
Read more >
Adding dark mode with Next.js, styled-components, and ...
Based on this preference, we actually have to dynamically update all the colors in our app. To do this, I defined light, dark,...
Read more >
The Quest for the Perfect Dark Mode - Josh W Comeau
The reason that this problem is so dastardly has to do with how frameworks like Gatsby/Next.js work; the HTML is generated ahead of...
Read more >
Dark theme - Android Developers
This ties the app's main theme to the system-controlled night mode flags and gives the app a default Dark theme (when it is...
Read more >
The Complete Guide to Dark Mode with Remix | Matt Stobbs
To add a dark mode using CSS variables, create a variable for each colour that will be affected by the change in themes....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found