spaceleafio
spaceleafio

Reputation: 1

Chakra UI Next Js - Color Mode Toggle takes 2 clicks on Mobile to change Background Color

I'm getting a bit of a weird issue trying to rig up a ColorMode Toggle on a NextJs project using Chakra UI to get light and dark modes working.

I have it implemented to the best of my knowledge following their docs and on desktop it works as intended. I am trying to pull info from cookies for colorModeManager to take care of SSR.

My issue is when trying the toggle on mobile, everything in the theme switches correctly except for the background color on the first toggle attempt. Ie, text goes from black to light, but background stays from light to light, resulting in a screen with both light background and text. When i hit the toggle again for the second time, the background now changes from light to dark as it should have the first click, the text and other components switch again, resulting in everything being masked by being stuck in opposite colormodes.

would very much appreciate any insights as to why this might be happening and how to adjust to fix. I can't replicate it on my local machine in browser, just when i deploy to vercel and it's only broken this way on mobile.

Chakra.jsx

import {
  ChakraProvider,
  cookieStorageManager,
  localStorageManager
} from '@chakra-ui/react';
import theme from '../../styles/theme';

export function Chakra({ cookies, children }) {

  const colorModeManager =
    typeof cookies === 'string'
      ? cookieStorageManager(cookies)
      : localStorageManager

  return (
    <ChakraProvider colorModeManager={colorModeManager} theme={theme}>
        {children}
    </ChakraProvider>
  )
}

// also export a reusable function getServerSideProps
export function getServerSideProps({ req }) {
  return {
    props: {
      // first time users will not have any cookies and you may not return
      // undefined here, hence ?? is necessary
      cookies: req.headers.cookie ?? '',
    },
  }
}

ToggleTheme.jsx

import { useColorMode, useColorModeValue, IconButton, Icon } from '@chakra-ui/react';
import { SunIcon, MoonIcon } from '@chakra-ui/icons';

export default function ToggleTheme() {
  const { colorMode, toggleColorMode } = useColorMode()

  return (
    <>
       <IconButton
          aria-label='Toggle Theme'
          icon={colorMode === 'light' ? <SunIcon /> : <MoonIcon />}
          onClick={toggleColorMode}/>
    </>
  )
}

_app.js

import * as React from 'react';
import '../styles/globals.scss';
import '../styles/content.scss';
import { motion, AnimatePresence } from 'framer-motion';
import { Chakra } from '../components/theme/Chakra'
import Layout from '../components/layout/Layout'


function MyApp({ Component, pageProps, router }) {

  return (
    <>
      <Chakra cookies={pageProps.cookies}>
        <Layout>
           <Component {...pageProps} />
        </Layout>
       </Chakra>

      </>
  );
}

export default MyApp;

 // re-export the reusable `getServerSideProps` function
export { getServerSideProps } from "../components/theme/Chakra";

theme.js

import { extendTheme } from '@chakra-ui/react';
import { mode } from '@chakra-ui/theme-tools';


const config = {
  initialColorMode: 'light',
  useSystemColorMode: false,
}
 
const overrides = {
  config
}

const theme = extendTheme(overrides)

export default theme

Upvotes: 0

Views: 1269

Answers (1)

Adam Duro
Adam Duro

Reputation: 882

The problem is re-exporting from _app.js. You actually need to re-export from the pages (index.ts). _app.js does not support getServerSideProps

Upvotes: 1

Related Questions