donavon / use-dark-mode

A custom React Hook to help you implement a "dark mode" component.
MIT License
1.28k stars 100 forks source link

Errors with SSR on Next.js #55

Open janhesters opened 4 years ago

janhesters commented 4 years ago

Sometimes, the value on the server doesn't match the one on the client (when doing SSR).

Warning: Prop `aria-label` did not match. Server: "Dark Mode" Client: "Light Mode"

I did include noflash.js.

smugller commented 3 years ago

Yea I've got the same problem. It looks like you changed the className only on client side when press the Dark Mode Toggle button. When you change from Light Theme to Dark Theme and refresh the page, the className of client it's different from server that's why the data which is generated by server is different and inconsistent with client. Idk how to deal with that, anyone have a solution ?

jofelipe commented 3 years ago

I didn't find a solution, even with babel plugin, and styled components example. :(

The only solution I found to use dark mode with Next SSG without store any data on my server, was this one using CSS Variables by @hangindev (thank you)

I hope it helps someone :)

smugller commented 3 years ago

I found a little bit better explained tutorial about this problem. CSS Variables is the only and best way to do this. If you understand the problem about CSR / SSR inconsistent data, then better for you, because you start using CSS Variables which are awesome. Here is explained more about SSR Dark Mode -> https://joshwcomeau.com/gatsby/dark-mode/

velut commented 3 years ago

I found that using a dynamic import with no SSR for components that rely on dark mode state for rendering works.

For example, I have a Navbar component containing a ThemeButton component that toggles the dark mode status.

I import the ThemeButton in my Navbar component like this:

// Navbar.tsx

const ThemeButton = dynamic(
    (() =>
        import('./ThemeButton').then(({ ThemeButton }) => ThemeButton)) as any,
    { ssr: false }
) as any;

and then I normally use <ThemeButton /> in the Navbar template.

Now ThemeButton will be rendered only in the browser, removing any SSR related data inconsistencies.