Skip to main content
Version: 5.xx.xx
Source Code

<ThemedLayout />

Modern admin dashboards should support both light and dark themes. Users often prefer dark mode for late-night work, while others prefer light mode during the day. This theme system provides everything you need to add theme switching to your Refine app.

The system includes a provider for theme management, toggle buttons for quick switching, and dropdown selectors for explicit theme choice. It automatically saves the user's preference and supports system theme detection.

Installation

Add the theme system to your project:

npx shadcn@latest add https://ui.refine.dev/r/theme-provider.json

This installs the complete theme system with light/dark/system theme support.

Setup

First, wrap your app with the theme provider:

import { ThemeProvider } from "@/components/refine-ui/theme/theme-provider";

function App() {
return (
<ThemeProvider defaultTheme="system" storageKey="refine-ui-theme">
{/* Your app content */}
</ThemeProvider>
);
}

The defaultTheme="system" means it will automatically match the user's operating system preference. The theme choice is automatically saved to localStorage so users don't have to re-select their preference.

Adding Theme Controls

Now you can add theme switching controls to your layout. The most common approach is adding a theme toggle to your header:

import { ThemeToggle } from "@/components/refine-ui/theme/theme-toggle";
import { ThemeSelect } from "@/components/refine-ui/theme/theme-select";

function Layout() {
return (
<div>
<header className="flex items-center justify-between p-4">
<h1>My Admin Dashboard</h1>
{/* Quick theme toggle button */}
<ThemeToggle />
</header>

{/* Or use a dropdown in user menus */}
<nav>
<ThemeSelect />
</nav>
</div>
);
}

The ThemeToggle cycles through light → dark → system themes with each click. The ThemeSelect shows a dropdown with explicit options.

Custom Theme Control

You can also build custom theme controls using the useTheme hook:

import { useTheme } from "@/components/refine-ui/theme/theme-provider";

function CustomThemeButton() {
const { theme, setTheme } = useTheme();

return (
<div className="flex gap-2">
<span>Current: {theme}</span>
<button onClick={() => setTheme("light")}>Light</button>
<button onClick={() => setTheme("dark")}>Dark</button>
<button onClick={() => setTheme("system")}>System</button>
</div>
);
}

API Reference

ThemeProvider

PropTypeDefaultDescription
childrenReactNode-Child components
defaultTheme"light" \| "dark" \| "system""system"Default theme when none is stored
storageKeystring"refine-ui-theme"localStorage key for persistence

ThemeToggle

Cycling button that switches between themes.

PropTypeDescription
classNamestringAdditional CSS classes

ThemeSelect

Dropdown menu for theme selection.

useTheme Hook

Return ValueTypeDescription
theme"light" \| "dark" \| "system"Current theme
setTheme(theme: "light" \| "dark" \| "system") => voidFunction to change theme