shadcn-ui/ui · error · Error

useTheme must be used within a ThemeProvider

Error message

useTheme must be used within a ThemeProvider

What it means

useTheme reads ThemeProviderContext. <ThemeProvider> deliberately initializes the context with an explicit undefined default (createContext<... | undefined>(undefined)), so the hook can distinguish 'no provider at all' from 'provider with a real value'. If the context is still undefined at a consumer, there is no <ThemeProvider> ancestor and the hook throws, since dark/light state would otherwise be undefined.

Source

Thrown at templates/vite-app/src/components/theme-provider.tsx:226

    () => ({
      theme,
      setTheme,
    }),
    [theme, setTheme]
  )

  return (
    <ThemeProviderContext.Provider {...props} value={value}>
      {children}
    </ThemeProviderContext.Provider>
  )
}

export const useTheme = () => {
  const context = React.useContext(ThemeProviderContext)

  if (context === undefined) {
    throw new Error("useTheme must be used within a ThemeProvider")
  }

  return context
}

View on GitHub (pinned to efac598707)

Solutions

  1. Wrap the app (or route layout) in <ThemeProvider defaultTheme=... storageKey=...>.
  2. Ensure the provider is an ancestor of every component calling useTheme.
  3. For portals/modals, render them within the provider subtree or add a nested provider.

Example fix

// before
<Root />
// Root.tsx: const { theme } = useTheme() // no ThemeProvider above

// after
<ThemeProvider defaultTheme="dark" storageKey="vite-ui-theme">
  <Root />
</ThemeProvider>
Defensive patterns

Strategy: validation

Validate before calling

function useOptionalTheme() {
  const ctx = React.useContext(ThemeProviderContext)
  return ctx // undefined when no provider
}
const theme = useOptionalTheme()
if (!theme) return null

Type guard

function useHasThemeProvider(): boolean {
  return React.useContext(ThemeProviderContext) !== undefined
}

Prevention

When it happens

Trigger: Calling useTheme() in a component rendered above/outside <ThemeProvider>; mounting a themed component in a route/layout the provider does not cover; portal content rendered outside the provider subtree.

Common situations: Moving ThemeProvider from the root to a subset of routes; Storybook stories rendering a theme toggle without the provider; refactor that lifts a consumer above the provider.

Related errors


AI-assisted analysis of shadcn-ui/ui@efac598707 (2026-08-12). Data as JSON: /api/errors/6e3a830502ceb00c. Report an issue: GitHub.