Dark mode works out of the box via ColorModeProvider. Colors are standard Bootstrap 5.3 CSS variables.
How dark mode works
DashboardLayout wraps your app in a ColorModeProvider. It manages three modes — light, dark, and auto — and:
- sets
data-bs-theme="light"or"dark"on the<html>element (Bootstrap 5.3's native theming hook); - resolves
autofrom the user'sprefers-color-schemeand live-updates when the system theme changes; - persists the choice to
localStorageunder the keylte-themeand restores it on load.
Set the starting mode with initialColorMode on DashboardLayout. A saved preference overrides it on the next visit.
<DashboardLayout menuItems={menuItems} initialColorMode="auto" colorModeToggle>
{children}
</DashboardLayout>The toggle
When colorModeToggle is true (the default), a light/dark/auto toggle appears in the topbar. You can also drop ColorModeToggle anywhere inside the layout, or build your own control with the context hook.
Reading & setting the mode
Use useColorModeContext() from any client component inside the layout.
'use client'
import { useColorModeContext } from 'adminlte-react'
function ThemeButtons() {
const { colorMode, setColorMode, resolvedMode } = useColorModeContext()
return (
<div className="btn-group">
<button onClick={() => setColorMode('light')}>Light</button>
<button onClick={() => setColorMode('dark')}>Dark</button>
<button onClick={() => setColorMode('auto')}>Auto</button>
<span>active: {colorMode} (resolved: {resolvedMode})</span>
</div>
)
}Context value
| Prop | Type | Default | Description |
|---|---|---|---|
colorMode | 'light' | 'dark' | 'auto' | — | The selected mode. |
setColorMode | (mode: ColorMode) => void | — | Change the mode (also persists it). |
resolvedMode | 'light' | 'dark' | — | The concrete mode in effect after resolving 'auto'. |
Customizing colors
Components use standard Bootstrap 5.3 theme classes (text-bg-primary, card-success, etc.) and CSS variables. Override the variables in your globals.css to rebrand without touching component code. Scope overrides under [data-bs-theme="dark"] to change dark-mode values independently.
:root {
--bs-primary: #6f42c1;
--bs-primary-rgb: 111, 66, 193;
--bs-border-radius: 0.5rem;
}
[data-bs-theme="dark"] {
--bs-body-bg: #11131a;
}Sidebar theme
The sidebar has its own light/dark treatment, independent of the page color mode. Control it with sidebarTheme on DashboardLayout (default dark), and add utility classes with sidebarClass.
<DashboardLayout menuItems={menuItems} sidebarTheme="light" sidebarClass="bg-body shadow-sm">
{children}
</DashboardLayout>Persistence keys
The library writes two localStorage keys:
| Prop | Type | Default | Description |
|---|---|---|---|
lte-theme | localStorage | — | The selected color mode ('light' | 'dark' | 'auto'). |
lte.sidebar.state | localStorage | — | Sidebar collapsed state — only when enableSidebarPersistence is set. |
Right-to-left (RTL)
Pass dir="rtl" to mirror the entire layout. AdminLTE 4 / Bootstrap 5.3 use CSS logical properties, but AdminLTE’s component styles are compiled LTR — so for a pixel-perfect flip, also load the dedicated adminlte.rtl.css build on RTL routes (after the LTR CSS so it wins the cascade).
<DashboardLayout menuItems={menuItems} dir="rtl">
{children}
</DashboardLayout>'use client'
import { useEffect } from 'react'
// Load AdminLTE's RTL build only on RTL routes
export function RtlStyles() {
useEffect(() => {
const link = document.createElement('link')
link.rel = 'stylesheet'
link.href = '/css/adminlte.rtl.css'
document.head.append(link)
return () => link.remove()
}, [])
return null
}