Toggling Between Dark and Light Mode in Next.js: A Practical Approach
Implementing a dark and light mode toggle in a Next.js application can be a bit challenging due to the nature of server-side rendering (SSR). Unlike client-side environments, the server doesn’t have access to the user’s system preferences, making it tricky to determine the appropriate theme during initial rendering. However, through some experimentation and research, I’ve developed a method that simplifies this process.
Step 1: Defining Theme Styles in CSS
First, it’s crucial to declare all your color-related styles — such as text color, background color, and other related properties — using CSS variables. You’ll need to create two sets of variables, one for each theme. For instance:
:root {
--background-color: #ffffff;
--text-color: #000000;
}
.dark-mode {
--background-color: #000000;
--text-color: #ffffff;
}
.light-mode {
--background-color: #ffffff;
--text-color: #000000;
}
Step 2: Installing and Setting Up next-themes
To handle theme switching efficiently, I recommend using the next-themes
package. Using npm: npm install next-themes, Using yarn: yarn add next-themes. This library provides a straightforward way to manage themes in Next.js applications. After installing the package, you'll need to set up a ThemeProvider
context.
Step 3: Creating a Theme Provider
Create a new component for your ThemeProvider using the following code:
"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 <NextThemesProvider {...props}>{children}</NextThemesProvider>;
}
Step 4: Wrapping Your Application with the Theme Provider
Typically, in Next.js, you would wrap your entire application in this provider at the root level, like in the _app.js
or layout.js
file.
import { ThemeProvider } from "@/components/ThemeProvider";
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
<ThemeProvider>
{children}
</ThemeProvider>
</body>
</html>
);
}
Setting Up the Toggle Mode
Now, you can create a button that toggles between dark and light mode using the useTheme
hook provided by next-themes
. Here's a basic example:
import { useTheme } from "next-themes";
export default function ThemeToggle() {
const { theme, setTheme } = useTheme();
const toggleTheme = () => {
setTheme(theme === "light" ? "dark" : "light");
};
return (
<button onClick={toggleTheme}>
{theme === "light" ? "Switch to Dark Mode" : "Switch to Light Mode"}
</button>
);
}
Conclusion
By following these steps, you can successfully implement a dark and light mode toggle in your Next.js application. The key is to manage your styles via CSS variables and use the next-themes
package to handle theme switching seamlessly.