--- description: Configure dark mode for your framework argument-hint: "[framework]" allowed-tools: Read, Write, Edit, Bash --- Set up dark mode with theme switching for your specific framework. ## Instructions Based on the framework detected or specified: 1. Install required dependencies 2. Set up theme provider 3. Configure CSS variables 4. Create theme toggle component 5. Set up persistence (cookies/localStorage) ## Framework Configurations ### Next.js (App Router) ```bash npm install next-themes ``` Create `components/theme-provider.tsx`: ```tsx "use client" import * as React from "react" import { ThemeProvider as NextThemesProvider } from "next-themes" import { type ThemeProviderProps } from "next-themes/dist/types" export function ThemeProvider({ children, ...props }: ThemeProviderProps) { return {children} } ``` Wrap in `app/layout.tsx`: ```tsx {children} ``` ### Vite Create `components/theme-provider.tsx`: ```tsx import { createContext, useContext, useEffect, useState } from "react" type Theme = "dark" | "light" | "system" const ThemeProviderContext = createContext<{ theme: Theme setTheme: (theme: Theme) => void }>({ theme: "system", setTheme: () => null, }) export function ThemeProvider({ children }: { children: React.ReactNode }) { const [theme, setTheme] = useState( () => (localStorage.getItem("theme") as Theme) || "system" ) useEffect(() => { const root = window.document.documentElement root.classList.remove("light", "dark") if (theme === "system") { const systemTheme = window.matchMedia("(prefers-color-scheme: dark)") .matches ? "dark" : "light" root.classList.add(systemTheme) return } root.classList.add(theme) }, [theme]) const value = { theme, setTheme: (theme: Theme) => { localStorage.setItem("theme", theme) setTheme(theme) }, } return ( {children} ) } export const useTheme = () => { const context = useContext(ThemeProviderContext) if (context === undefined) throw new Error("useTheme must be used within a ThemeProvider") return context } ``` ### Remix ```bash npm install remix-themes ``` In `app/root.tsx`: ```tsx import { themeSessionResolver } from "remix-themes" import { PreventFlashOnWrongTheme, ThemeProvider, useTheme, } from "remix-themes" export async function loader({ request }: LoaderFunctionArgs) { const { getTheme } = await themeSessionResolver(request) return { theme: getTheme() } } export default function App() { const data = useLoaderData() const [theme] = useTheme() return ( ) } ``` ### Astro In layout file: ```astro ``` ## Theme Toggle Component Create `components/theme-toggle.tsx`: ```tsx import { Moon, Sun } from "lucide-react" import { Button } from "@/components/ui/button" import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu" import { useTheme } from "@/components/theme-provider" // or "next-themes" export function ThemeToggle() { const { setTheme } = useTheme() return ( setTheme("light")}> Light setTheme("dark")}> Dark setTheme("system")}> System ) } ``` ## CSS Configuration Ensure `globals.css` has: ```css @layer base { :root { --background: 0 0% 100%; --foreground: 222.2 84% 4.9%; /* ... other variables ... */ } .dark { --background: 222.2 84% 4.9%; --foreground: 210 40% 98%; /* ... other variables ... */ } } ``` ## Example If the user says: `/setup-dark-mode next` 1. Install next-themes 2. Create ThemeProvider component 3. Wrap app in ThemeProvider 4. Create ThemeToggle component 5. Add to navigation/header 6. Test theme switching