Skip to content

Dark Mode ​

Every ShadcnStore block ships with dark mode built in. Each block uses shadcn/ui design tokens and Tailwind dark: variants, so it adapts automatically once your app toggles the dark class on the <html> element. You do not need to edit any block code.

How it works ​

Blocks reference CSS variables (for example bg-background, text-foreground) that resolve to different values under the .dark class. Your job is to add and persist that class. Toggling it flips every block at once.

Next.js ​

Use next-themes, which persists the choice and avoids a flash of the wrong theme on load.

bash
npm install next-themes
tsx
// app/providers.tsx
"use client"
import { ThemeProvider } from "next-themes"

export function Providers({ children }: { children: React.ReactNode }) {
  return (
    <ThemeProvider attribute="class" defaultTheme="system" enableSystem>
      {children}
    </ThemeProvider>
  )
}

Wrap your app in <Providers> and toggle with useTheme():

tsx
"use client"
import { useTheme } from "next-themes"
import { Button } from "@/components/ui/button"

export function ModeToggle() {
  const { theme, setTheme } = useTheme()
  return (
    <Button variant="outline" size="icon"
      onClick={() => setTheme(theme === "dark" ? "light" : "dark")}>
      Toggle theme
    </Button>
  )
}

Vite (or plain React) ​

There is no framework provider, so persist the choice yourself. This reads the saved theme, falls back to the system preference, and stores changes so they survive a reload:

tsx
import { useEffect, useState } from "react"

export function useDarkMode() {
  const [isDark, setIsDark] = useState(() => {
    const saved = localStorage.getItem("theme")
    if (saved) return saved === "dark"
    return window.matchMedia("(prefers-color-scheme: dark)").matches
  })

  useEffect(() => {
    document.documentElement.classList.toggle("dark", isDark)
    localStorage.setItem("theme", isDark ? "dark" : "light")
  }, [isDark])

  return { isDark, toggle: () => setIsDark((v) => !v) }
}

To avoid a flash before hydration, set the class in an inline script in your index.html <head> before the app loads.