Back to Chakra Ui

Color Mode

apps/www/content/docs/components/concepts/color-mode.mdx

0.3.0-beta4.6 KB
Original Source

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.

bash
npx @chakra-ui/cli snippet add color-mode

The snippet includes hooks and components that make it feel similar to Chakra v2.

tsx
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.

<ExampleTabs name="color-mode-basic" />

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:

tsx
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.

<ExampleTabs name="color-mode-value" />

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.

<ExampleTabs name="color-mode-value-fallback" />

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.

<ExampleTabs name="color-mode-icon-button" />

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.

<ExampleTabs name="color-mode-forced" />

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:

tsx
export function ColorModeProvider(props: ColorModeProviderProps) {
  return (
    <ThemeProvider
      attribute="class"
      disableTransitionOnChange
      defaultTheme="light"
      {...props}
    />
  )
}

Default to dark mode:

tsx
export function ColorModeProvider(props: ColorModeProviderProps) {
  return (
    <ThemeProvider
      attribute="class"
      disableTransitionOnChange
      defaultTheme="dark"
      {...props}
    />
  )
}

Respect system preference (default):

tsx
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.

tsx
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.

tsx
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.

tsx
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.