Using appearance to manage and integrate dark mode.
Light and dark modes are supported out of the box, allowing you to easily switch appearance without additional design or styling.
By default, the root Theme appearance is light. To set a different appearance pass it via the appearance prop. This will force the theme to use the specified setting.
<Theme appearance="dark">
<MyApp />
</Theme>
Radix Themes will automatically set the background color of your app to match appearance, this is achieved by injecting a background-color style on the body element.
As the style injection can only occur on the client, you may experience a hydration warning. In this case it's safe to suppress the warning.
// app/layout.jsx
export default function Layout({ children }) {
return (
<html suppressHydrationWarning>
<head />
<body>{children}</body>
</html>
);
}
A common requirement is to inherit the appearance setting from a users system preferences.
This is a deceptively complex problem to solve given SSR, SSG and client side hydration considerations. To make implementation easier, we recommend integrating with a theme switching library.
Integration with next-themes is simple and straightforward because Radix Themes implements matching class names.
To enable dark mode, use <ThemeProvider> from next-themes with attribute="class".
import { Theme } from '@radix-ui/themes';
import { ThemeProvider } from 'next-themes';
export default function () {
return (
<ThemeProvider attribute="class">
<Theme>
<MyApp />
</Theme>
</ThemeProvider>
);
}
Do not pass resolvedTheme from next-themes to appearance. Instead, rely just on the class switching. This is important so that next-themes can prevent the appearance flash during initial render.
Any library that supports class switching is compatible, you'll just need to ensure that the appended class names match those used by Radix Themes:
lightdarkor
light-themedark-theme