# Dark Mode **Category**: react **URL**: https://www.blakeui.com/en/docs/react/getting-started/dark-mode **Source**: https://raw.githubusercontent.com/myblakebox/BlakeUI/refs/heads/main/apps/docs/content/docs/en/react/getting-started/(handbook)/dark-mode.mdx > Add light, dark, and system theme switching to blakeUI *** blakeUI dark mode is CSS-driven. Components read theme variables from the root element, so you do not need a blakeUI provider. Add the `dark` class or `data-theme="dark"` to `` and blakeUI will apply the dark theme. ```html ``` Keep the `bg-background` and `text-foreground` classes on your app shell so the page canvas changes with the active theme. blakeUI's built-in light and dark themes respond to both `.light` / `.dark` classes and `data-theme="light"` / `data-theme="dark"` attributes. If you set both manually, keep the values in sync. ## Next.js with next-themes Use [next-themes](https://github.com/pacocoursey/next-themes) when you need theme persistence, system preference support, and no flash before hydration in a Next.js app. ### Install next-themes ```bash npm i next-themes ``` ```bash pnpm add next-themes ``` ```bash yarn add next-themes ``` ```bash bun add next-themes ``` ### App Router Create a client provider for `next-themes`. ```tsx // app/providers.tsx "use client"; import {ThemeProvider as NextThemesProvider} from "next-themes"; export function Providers({children}: {children: React.ReactNode}) { return ( {children} ); } ``` Wrap your app with the provider from the root layout. Add `suppressHydrationWarning` to `` because `next-themes` updates that element before hydration. ```tsx // app/layout.tsx import "./globals.css"; import {Providers} from "./providers"; export default function RootLayout({children}: {children: React.ReactNode}) { return ( {children} ); } ``` ### Theme switcher Use `useTheme` from `next-themes` inside a client component. Delay rendering until mount because the active theme is not known during SSR. ```tsx // app/components/theme-switcher.tsx "use client"; import {Button} from "@blakeui/react"; import {useTheme} from "next-themes"; import {useEffect, useState} from "react"; export function ThemeSwitcher() { const [mounted, setMounted] = useState(false); const {resolvedTheme, setTheme, theme} = useTheme(); useEffect(() => { setMounted(true); }, []); if (!mounted) return null; const activeTheme = theme === "system" ? resolvedTheme : theme; return (
); } ``` ### Pages Router For `pages/`, wrap your application in `pages/_app.tsx`. ```tsx // pages/_app.tsx import "@/styles/globals.css"; import type {AppProps} from "next/app"; import {ThemeProvider as NextThemesProvider} from "next-themes"; export default function App({Component, pageProps}: AppProps) { return ( ); } ``` ## Using custom theme names The `attribute="class"` setup works well for the built-in `light` and `dark` themes. If your custom theme CSS is written with `data-theme` selectors, configure `next-themes` to write `data-theme` instead. ```tsx {children} ``` When you pass a custom `themes` list, include `"light"` and `"dark"` if you still want the built-in themes available. ## React with useTheme Use blakeUI's `useTheme` hook when you are building a plain React app, such as Vite or Create React App, and do not need `next-themes`. The hook is exported from `@blakeui/react`. It stores the selected theme in `localStorage`, resolves `"system"` from the user's OS preference, and applies both the class and `data-theme` attribute to ``. ```tsx // src/components/theme-switcher.tsx import {Button, useTheme} from "@blakeui/react"; export function ThemeSwitcher() { const {resolvedTheme, setTheme, theme} = useTheme("system"); return (
); } ``` Use one theme controller per app. In Next.js, prefer `next-themes` and its `useTheme` hook. In plain React apps, use `useTheme` from `@blakeui/react`. ## Styling for both themes Theme-aware utilities work automatically because they read CSS variables: ```tsx
Theme-aware content
``` Use the `dark:` variant for one-off changes that only apply in dark mode: ```tsx
Custom dark-mode adjustment
```