Preview
Installation
CLI
npx shadcn@latest add https://kelvinmai.io/r/theme-switch.json
Manual
Install the following dependencies
npm install next-themes
Set up next-themes in your Next.js app
app/layout.tsx
import { ThemeProvider } from 'next-themes';export default function RootLayout({children,}: Readonly<{children: React.ReactNode;}>) {return (<ThemeProvider attribute='class' defaultTheme='system' enableSystem>{children}</ThemeProvider>);}
To develop your own themes you can get some inspiration or customize your own from tweakcn.
Copy and paste the following code into your project
hooks/use-theme.ts
'use client';import * as React from 'react';import { useTheme as useNextTheme } from 'next-themes';export const colorThemes = [Add your own theme names here'default','bubblegum','monochrome','supabase','twitter','vercel',] as const;export type ColorTheme = (typeof colorThemes)[number];export type Theme = 'system' | 'light' | 'dark';export const useTheme = () => {const { setTheme, resolvedTheme } = useNextTheme();const [colorTheme, setColorTheme] = React.useState<ColorTheme>('default');React.useEffect(() => {if (typeof window === 'undefined') return;const saved = localStorage.getItem('color-theme') as ColorTheme | null;if (saved) {setColorTheme(saved);document.documentElement.classList.add(`theme-${saved}`);}}, []);const updateColorTheme = React.useCallback((next: ColorTheme) => {if (typeof window === 'undefined') return;document.documentElement.classList.remove(...colorThemes.map((c) => `theme-${c}`),);if (next !== 'default') {document.documentElement.classList.add(`theme-${next}`);}localStorage.setItem('color-theme', next);setColorTheme(next);}, []);return {setTheme,theme: resolvedTheme as Theme,colorTheme: colorTheme,setColorTheme: updateColorTheme,};};
Update the import paths to match your project setup
Usage
Add multiple custom themes to your global css file
app/globals.css
.theme-yours {By default this hook assumes theme names are prefixed with `theme-`/* ... */}.theme-yours.dark {/* ... */}
import { useTheme } from '@/hooks/use-theme';const { theme, setTheme, colorTheme, setColorTheme } = useTheme();
API Reference
Returns
The useToggle
hook returns an object with the following elements:
Name | Type | Description |
---|---|---|
theme | Theme | The resolved theme provided by next-themes. |
setTheme | (Theme) => void | Function to set the next-theme theme. |
colorTheme | ColorTheme | The current theme of your pre-defined shadcn color theme. |
setColorTheme | (ColorTheme) => void | Function to set the the color theme. |