0

i am working on NextJs Project for the project i was required to create a theme switcher i am using MUIv5 as styling foundation and i have managed to create a theme switcher which switch between different color schemes and fonts even persisted the same selected theme in cookies as nextjs doesnt support localStorage on 1st render page loads with default theme after selecting a desired theme and reloading the page i get hydration error from nextjs i tried disabling hydration for entire app passed use Client flag but its not working.

i am attaching the code snippets below to give you clear understanding of what i have done what needs to done to fix issue

_app.js

const themesArr = [
  {
    name: "Default",
    themeName: theme,
  },
  {
    name: "Green",
    themeName: theme1,
  }, ... so on
  {/* theme array needs to be mapped over the select dropdown. */}
  
];

State handling of dropdown

const [selectedThemeName, setSelectedThemeName] = useState(
    cookie.get("selectedThemeName") || "Default"
  );
  const [selectedTheme, setSelectedTheme] = useState(
    themesArr.find((theme) => theme.name === selectedThemeName).themeName
  );
  const handleChange = (event) => {
    const newThemeName = event.target.value;
    setSelectedThemeName(newThemeName);
    setSelectedTheme(
      themesArr.find((theme) => theme.name === newThemeName).themeName
    );
    cookie.set("selectedThemeName", newThemeName, { expires: 365 });
  };

JSX Code of Select

  <Select
                  sx={{
                    backgroundColor: "primary.main",
                    color: "common.white",
                    maxWidth: "90px",
                  }}
                  autoWidth
                  value={selectedThemeName}
                  onChange={handleChange}
                >
                  {themesArr.map((theme) => (
                    <MenuItem key={theme.name} value={theme.name}>
                      {theme.name}
                    </MenuItem>
                  ))}
                </Select>

Error Text Error: Text content does not match server-rendered HTML.

See more info here: https://nextjs.org/docs/messages/react-hydration-error

i tried disabling hydration in my app added flag of use Client to render it only on client took help from chatgpt even chatgpt told me take help from nextjs and material-ui community

1 Answers1

0

I recently had a similar issue. You can try using next-themes - npm package. It will allow you to have access to the resolvedTheme which you can use in your switch component.

Having said that, it will not fix the hydration issue itself. The reason for this issue is that the server doesn't have access to the theme itself. So what you can do is use useEffect and useState to determine if the component is mounted then to change the theme accordingly.

ie:

import { useState, useEffect } from 'react'
import { useTheme } from 'next-themes'

const ThemeSwitch = () => {
  const [mounted, setMounted] = useState(false)
  const { theme, setTheme } = useTheme()

  // useEffect only runs on the client, so now we can safely show the UI
  useEffect(() => {
    setMounted(true)
  }, [])

  if (!mounted) {
    return null
  }

this is all from the next-themes docs

alltrust
  • 61
  • 5