Switching between system, dark, and light mode

I am using MUI in my Next.js web app to switch between system, light, and dark mode. I am having it persist between sessions by saving the theme selected in local storage. I have placed the ability to change the theme of the web app within a dropdown in the settings modal, so changing of the theme occurs through a useContext. The issue I’m encountering is that theming is not persistent across all of my components if the theme the user selects is either the “system” theme (if your system them is dark mode), or “dark” theme. In addition, I also receive this error if my theme is not “light” theme on initial load or when switching from “light” theme to one of the others:

Warning: Prop `className` did not match. Server: "MuiButtonBase-root MuiIconButton-root MuiIconButton-colorInherit MuiIconButton-edgeStart MuiIconButton-sizeMedium css-134qg7o-MuiButtonBase-root-MuiIconButton-root" Client: "MuiButtonBase-root MuiIconButton-root MuiIconButton-colorInherit MuiIconButton-edgeStart MuiIconButton-sizeMedium css-6pxnsq-MuiButtonBase-root-MuiIconButton-root

After some searching, I originally thought it was because I had not been using CssBaseline within the ThemeProvider tags, however, after adding it, it appears to have only made things worse, and the error persists. I will show the different behavior in screenshots below:

Expected behavior if in “system” or “dark” mode (This is without CssBaseline between the ThemeProvider tags:
enter image description here

The actual behavior without CssBaseline on load in with “system” or “dark” mode:
enter image description here

The behavior on load when in “system” or “dark” mode with CssBaseline:
enter image description here

The behavior when switching from “light” mode to “system” or “dark” mode:
enter image description here

Listed below is my context code and how I’m getting the theme from the system, how I’m storing it in local storage, and how I’m switching it:

const ThemeContext = createContext()

const useThemeContext = () => useContext(ThemeContext)

export const ThemeModeProviderComponent = ({ children }) => {
  const systemTheme = typeof window !== 'undefined' && window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'

  const [selectedTheme, setSelectedTheme] = useState(() =>
    typeof localStorage !== 'undefined' && localStorage.getItem('theme') || 'system'
  )

  const themes = {
    light: createTheme({
      palette: {
        mode: 'light',
        primary: {
          main: '#0065bd'
        },
        secondary: {
          main: '#00b6d3'
        }
      }
    }),
    dark: createTheme({
      palette: {
        mode: 'dark',
        primary: {
          main: '#0065bd'
        },
        secondary: {
          main: '#00b6d3'
        }
      }
    }),
    system: createTheme({
      palette: {
        mode: systemTheme,
        primary: {
          main: '#0065bd'
        },
        secondary: {
          main: '#00b6d3'
        }
      }
    })
  }

  useEffect(() => {
    if (selectedTheme === 'system') {
      const systemTheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
      themes.system.palette.mode = systemTheme
    }
  }, [selectedTheme, themes.system])

  const handleThemeChange = (event) => {
    const { value } = event.target

    setSelectedTheme(value)
    localStorage.setItem('theme', value)
  }

  return (
    <ThemeContext.Provider value={{ selectedTheme, handleThemeChange }}>
      <ThemeProvider theme={themes[selectedTheme]}>
          <CssBaseline enableColorScheme/>
          {children}
      </ThemeProvider>
    </ThemeContext.Provider>
  )
}

export const ThemeSelector = () => {
  const { selectedTheme, handleThemeChange } = useThemeContext()

  if (typeof window === 'undefined') return null

  return (
    <FormControl>
      <Select
        value={selectedTheme}
        onChange={handleThemeChange}
      >
        <MenuItem value='system'>System</MenuItem>
        <MenuItem value='dark'>Dark</MenuItem>
        <MenuItem value='light'>Light</MenuItem>
      </Select>
    </FormControl>
  )
}

Another possibility is that, because of the way I’m handling the showing and hiding of the drawer, it could be affecting the style. I basically copied the persistent drawer example from the MUI website here, but I don’t think it’s the case, as, as we’ve seen in the images, it it working properly to an extent.