git clone https://github.com/RV-React-Projects/NextJs-theme-Example.git
cd NextJs-theme-Examplebun installbun run devTo set up a custom theme toggle in your Next.js project without any external library, follow these steps:
Create a Theme Context:
Create a
ThemeContext.tsxfile in your project (e.g., inside acontextfolder):// context/ThemeContext.tsximportReact,{createContext,useContext,useState,useEffect,}from"react";typeTheme="light"|"dark";interfaceThemeContextProps{theme: Theme;toggleTheme: ()=>void;}constThemeContext=createContext<ThemeContextProps|undefined>(undefined);exportconstThemeProvider: React.FC<{children: React.ReactNode}>=({ children,})=>{const[theme,setTheme]=useState<Theme>("light");useEffect(()=>{conststoredTheme=localStorage.getItem("theme")asTheme;if(storedTheme)setTheme(storedTheme);},[]);useEffect(()=>{document.documentElement.setAttribute("data-theme",theme);localStorage.setItem("theme",theme);},[theme]);consttoggleTheme=()=>setTheme(theme==="light" ? "dark" : "light");return(<ThemeContext.Providervalue={{ theme, toggleTheme }}>{children}</ThemeContext.Provider>);};exportconstuseTheme=()=>{constcontext=useContext(ThemeContext);if(!context)thrownewError("useTheme must be used within ThemeProvider");returncontext;};
Update
global.css:Define your theme variables in
styles/global.css::root { --background:#fff; --text:#111; } [data-theme="dark"] { --background:#111; --text:#fff; } body { background:var(--background); color:var(--text); transition: background 0.2s, color 0.2s; }
Wrap your app with ThemeProvider:
In
app/layout.tsxor_app.tsx:import{ThemeProvider}from"../context/ThemeContext";import"../styles/global.css";exportdefaultfunctionRootLayout({ children }){return<ThemeProvider>{children}</ThemeProvider>;}
Add a Theme Toggle Button:
Use the context in your components:
import{useTheme}from"../context/ThemeContext";exportdefaultfunctionThemeToggle(){const{ theme, toggleTheme }=useTheme();return(<buttononClick={toggleTheme}> Switch to {theme==="light" ? "dark" : "light"} mode </button>);}
Now your Next.js app supports theme toggling without any external library!
- Sets a custom attribute (commonly named 'data-theme') on the root HTML element to apply a theme.
- Note: The attribute name 'data-theme' is just a convention; you can use any name or even set an attribute without a name directly, e.g.:
- document.documentElement.setAttribute(theme)
- This approach allows dynamic switching of themes by updating the attribute value.