How to add the Toggle Theme in Next.js 15 using Zustand and TailwindCSS
User prefer to use different theme on websites and application. Itβs better to have different Theme Mode according to the user preferences. Today, we will see how to implement such Theme Mode change feature in your website.
We are going to implement this feature in Next.js 15 with the help of Zustand (State Manage Tool) and Tailwind CSS. We will walk through how to implement Toggle theme in application.
Setting up the Project
To get started, we need to Next.js application with Tailwind.css Configured along with Zustand state management Library. You can use following command to create Next.js application with TailwindCss.
npx create-next-app@latest project-name
cd project-name
Above query creates Next.js Application. Run a below query in command line to Integrate Tailwind CSS with Next.js.
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
Now, Install Zustand in your application by simply running the below query.
npm install zustand immer persist
immer
and persist
are middleware libraries which are used in new version
Configured Files
Once application is create and Install all the required packages with need to configure files to complete Integration.
Modify the file tailwind.config.ts
by replacing the entire code.
// tailwind.config.js
import type { Config } from 'tailwindcss'
export default {
content: [
'./app/**/*.{js,ts,jsx,tsx,mdx}', // Note the addition of the `app` directory.
'./pages/**/*.{js,ts,jsx,tsx,mdx}',
'./components/**/*.{js,ts,jsx,tsx,mdx}',
// Or if using `src` directory:
'./src/**/*.{js,ts,jsx,tsx,mdx}',
],
theme: {
extend: {},
},
plugins: [],
} satisfies Config
You will see the global.css
file replace the content with below code.
@tailwind base;
@tailwind components;
@tailwind utilities;
Along with add below content in tsconfig.json
to setup Zustand.
// tsconfig.json
{
"compilerOptions": {
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}
Implementing Toggle Theme
Next.js makes it easy to implement toggle theme with Tailwind CSS. You can declared classes by pretending dark:
to the properties to indicate that they are dark Mode. For example, you can use dark:bg-gray-900
to change the background color to gray-900 when the theme is set to dark.
By default, Next.js uses the system preferences to set the theme. However, we also need to toggle between light and dark modes. To do this, we can set the darkMode
strategy to class
in the tailwind.config.js
file:
module.exports = {
darkMode: 'class',
// ...
}
With this configuration, Tailwind CSS will apply the theme when the dark class is present in the HTML tree.
Using Zustand to Create toggle Theme
Zustand is a state management library for React apps that helps manage and update application state. It's a lightweight, fast, and scalable tool that can be used to create and update global states.
To implement state management we need to create store
in Next.js
Create
store
folder inside app directory inside your projectInside
store
folder create a File name asTheme-Store.ts
// Theme-Store.ts
import { create } from "zustand";
import { immer } from "zustand/middleware/immer";
import { persist } from "zustand/middleware";
export interface ThemeProp {
themeMode: "light" | "dark";
toggleTheme: (theme: string) => void;
}
export const useThemeStore = create<ThemeProp>()(
persist(
immer((set) => ({
themeMode: "dark",
toggleTheme(theme: string) {
const newTheme = theme;
if (newTheme === "dark") {
set({ themeMode: "dark" });
} else {
set({ themeMode: "light" });
}
},
})),
{
name: "theme",
}
)
);
Create a
components
Folder inside which createThemeBtn.tsx
Copy the below code in
ThemeBtn.tsx
"use client";
import { Moon, Sun } from "lucide-react";
import { useEffect, useState } from "react";
import { useThemeStore } from "@/stores/theme-store";
export default function Header() {
const [themeMode, setThemeMode] = useState("dark");
const { toggleTheme } = useThemeStore();
const handleClick = () => {
const newMode = themeMode === "dark" ? "light" : "dark";
setThemeMode(newMode);
toggleTheme(newMode);
};
useEffect(() => {
document.querySelector("html")?.classList.remove("light", "dark");
document.querySelector("html")?.classList.add(themeMode);
}, [themeMode]);
return (
<div className="dark:bg-black bg-white text-black dark:text-white ">
<div className="flex m-3 mx-6 justify-between items-center">
<div
className=" dark:hover:bg-gray-800 hover:bg-gray-200 rounded-xl p-2"
onClick={handleClick}
>
{themeMode === "dark" ? <Moon /> : <Sun />}
</div>
</div>
</div>
);
}
Import the ThemeBtn.tsx
inside page.tsx
and now your application is good to go. Dark and Light theme is implemented.
Conclusion
I hope this article has helped you in implementing Toggle Theme.
Happy Coding π¨βπ». Do like and share the Post.
Also Check out My Blog Innoveda