BETTER-AUTH. UI
Plugins

Theme

Add theme selection with system, light, and dark modes to your authentication flow.

The theme plugin adds theme selection to your authentication UI. Users can switch between system, light, and dark themes from the user button dropdown and account settings.

Setup

Install the UI plugin

Run the shadcn CLI to install the theme plugin components:

npx shadcn@latest add @better-auth-ui/theme

Register the UI plugin

The plugin works with any theme library. Pass the theme library's hook, such as useTheme from next-themes.

The slot components can then read the current theme inside <ThemeProvider>. You do not need another wrapper.

components/providers.tsx
import { ThemeProvider, useTheme } from "next-themes"
import type { ReactNode } from "react"

import { AuthProvider } from "@/components/auth/auth-provider"
import { authClient } from "@/lib/auth-client"
import { themePlugin } from "@/lib/auth/theme-plugin"

export function Providers({ children }: { children: ReactNode }) {
  return (
    <ThemeProvider attribute="class" defaultTheme="system" enableSystem>
      <AuthProvider
        authClient={authClient}
        plugins={[
          themePlugin({ useTheme }) 
        ]}
      >
        {children}
      </AuthProvider>
    </ThemeProvider>
  )
}

The plugin calls useTheme() inside its slot components during each render. The call stays inside <ThemeProvider> when both providers share a component.

Or pass static theme state

If the theme source has no hook, pass both theme and setTheme. The source can use useState or a custom controller.

The plugin runs during each parent render. The slot components update when the state owner renders with a new value.

components/providers.tsx
const [theme, setTheme] = useState("system") 

<AuthProvider
  authClient={authClient}
  plugins={[
    themePlugin({ 
      theme, 
      setTheme, 
      themes: ["system", "light", "dark"] 
    }) 
  ]}
>
  {children}
</AuthProvider>

The two forms are mutually exclusive: you pass either useTheme or the theme/setTheme pair.

Components

<UserButton />

<Appearance />

Appearance

The <Appearance /> card is automatically rendered in <AccountSettings /> when the plugin is registered.

Usage

import { Appearance } from "@/components/auth/theme/appearance"

<Appearance />

Props

Prop

Type

Options

Prop

Type

Localization

Prop

Type

Last updated on

On this page