Color Mode
Adding support for light and dark color mode
Chakra UI relies on next-themes
to add support for light and dark color mode.
Setup
In most cases, you have it installed and set up by the CLI in the Provider
component. If not, you can install it manually.
npx @chakra-ui/cli snippet add color-modeThe snippet includes hooks and components that make it feel similar to Chakra v2.
import {
ColorModeButton,
DarkMode,
LightMode,
useColorMode,
useColorModeValue,
} from "@/components/ui/color-mode"useColorMode
The useColorMode hook returns the current color mode and a function to toggle
the color mode.
Calling toggleColorMode or setColorMode anywhere in your app tree toggles
the color mode from light or dark and vice versa.
useColorModeValue
The useColorModeValue hook returns a value based on the current color mode.
Here's the signature:
const result = useColorModeValue("<light-mode-value>", "<dark-mode-value>")The value returned will be the value of the light mode if the color mode is
light, and the value of the dark mode if the color mode is dark.
Hydration Mismatch
When using useColorModeValue or useColorMode in SSR, you may notice a
hydration mismatch when the page is mounted. This is because the color mode
value is computed on the server side.
To avoid this, use the ClientOnly component to wrap the component that uses
useColorModeValue and render a skeleton until mounted on the client side.
ColorModeButton
The color mode snippet comes with the ColorModeButton component built-in, you
can import it to render an icon button that toggles the color mode.
It renders a skeleton on the server side and the icon on the client side.
Forced Color Mode
The color mode snippet comes with the LightMode and DarkMode components
built-in, you can import it to force the color mode.
You might need to update the color-mode.tsx snippet since the LightMode
and DarkMode components were recently added to the snippet.
Guides
Setting Default Color Mode
To set the default color mode, update the ColorModeProvider in your
components/ui/color-mode.tsx file.
Default to light mode:
export function ColorModeProvider(props: ColorModeProviderProps) {
return (
<ThemeProvider
attribute="class"
disableTransitionOnChange
defaultTheme="light"
{...props}
/>
)
}Default to dark mode:
export function ColorModeProvider(props: ColorModeProviderProps) {
return (
<ThemeProvider
attribute="class"
disableTransitionOnChange
defaultTheme="dark"
{...props}
/>
)
}Respect system preference (default):
export function ColorModeProvider(props: ColorModeProviderProps) {
return (
<ThemeProvider
attribute="class"
disableTransitionOnChange
defaultTheme="system"
{...props}
/>
)
}Disabling System Preference
By default, the color mode respects the user's system preference. To disable
this and only use light or dark mode, set enableSystem to false.
export function ColorModeProvider(props: ColorModeProviderProps) {
return (
<ThemeProvider
attribute="class"
disableTransitionOnChange
defaultTheme="light"
enableSystem={false}
{...props}
/>
)
}Using Custom Storage Key
The color mode is stored in localStorage under the key theme. To use a
custom key, set the storageKey prop.
export function ColorModeProvider(props: ColorModeProviderProps) {
return (
<ThemeProvider
attribute="class"
disableTransitionOnChange
storageKey="my-app-color-mode"
{...props}
/>
)
}Forcing a Specific Page to Light/Dark Mode
To force a specific page to render in a specific color mode, set the
forcedTheme prop in the provider.
export function ColorModeProvider(props: ColorModeProviderProps) {
return (
<ThemeProvider
attribute="class"
disableTransitionOnChange
forcedTheme="dark"
{...props}
/>
)
}Alternatively, use the LightMode or DarkMode components to force specific
parts of your UI to render in a specific color mode.
FAQ
Does next-themes only work with Next.js?
No. Despite its name, next-themes is a general-purpose library that works with
any React framework including Vite, Remix, Gatsby, and others. The name can be
misleading, but it works great everywhere.