Creating a Dark Mode Toggle with Next.js and Tailwind CSS
As a web developer, you may be wondering how to create a dark mode toggle for your web application. In this tutorial, we will explore how to implement a dark mode toggle with Next.js and Tailwind CSS.
Introduction
Dark mode has become a popular feature in modern web applications. It provides a darker color palette that's easier on the eyes, especially in low-light environments. Implementing a dark mode toggle enhances user experience and accessibility. In this tutorial, we'll walk through the steps to create a dark mode toggle using Next.js and Tailwind CSS.
Prerequisites
Before we start, make sure you have the following installed:
- Node.js and npm
- Basic knowledge of React and Next.js
- Familiarity with Tailwind CSS
Setting Up the Project
Let's begin by creating a new Next.js project:
npx create-next-app my-app
Navigate to the project directory:
cd my-app
Install Tailwind CSS and its dependencies:
npm install tailwindcss postcss autoprefixer
Initialize Tailwind CSS configuration:
npx tailwindcss init -p
Configuring Tailwind CSS
Open the tailwind.config.js
file and enable dark mode by adding the darkMode
option:
module.exports = {
darkMode: 'class', // Enable class-based dark mode
content: [
'./pages/**/*.{js,ts,jsx,tsx}',
'./components/**/*.{js,ts,jsx,tsx}',
],
theme: {
extend: {},
},
plugins: [],
};
Update the globals.css
file in the styles
directory to include Tailwind's base styles:
@tailwind base;
@tailwind components;
@tailwind utilities;
Implementing the Dark Mode Toggle
We'll create a toggle button that allows users to switch between light and dark modes. Create a new file called ThemeToggle.js
in the components
directory:
import { useEffect, useState } from 'react';
const ThemeToggle = () => {
const [theme, setTheme] = useState('light');
// Set theme based on user's preference or system settings
useEffect(() => {
const storedTheme = localStorage.getItem('theme');
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
if (storedTheme) {
setTheme(storedTheme);
document.documentElement.classList.toggle('dark', storedTheme === 'dark');
} else if (prefersDark) {
setTheme('dark');
document.documentElement.classList.add('dark');
}
}, []);
const toggleTheme = () => {
const newTheme = theme === 'light' ? 'dark' : 'light';
setTheme(newTheme);
document.documentElement.classList.toggle('dark', newTheme === 'dark');
localStorage.setItem('theme', newTheme);
};
return (
<button onClick={toggleTheme} className="p-2">
{theme === 'light' ? '🌙' : '☀️'}
</button>
);
};
export default ThemeToggle;
This component checks local storage and system preferences to set the initial theme. It updates the classList
of document.documentElement
to apply the dark mode styles.
Updating the Application Layout
Include the ThemeToggle
component in your application. Modify the _app.js
file:
import '../styles/globals.css';
import ThemeToggle from "../components/ThemeToggle";
function MyApp({ Component, pageProps }) {
return (
<div className="min-h-screen bg-gray-100 dark:bg-gray-900 transition-colors">
<header className="flex justify-end p-4">
<ThemeToggle />
</header>
<main className="p-4 text-gray-900 dark:text-gray-100">
<Component {...pageProps} />
</main>
</div>
);
}
export default MyApp;
This setup ensures that the background and text colors adapt to the theme.
Styling Components for Dark Mode
Tailwind CSS allows you to apply styles conditionally based on the theme. Use the dark:
prefix to specify styles for dark mode. Update the index.js
file:
export default function Home() {
return (
<div>
<h1 className="text-4xl font-bold mb-4">
Next.js Dark Mode Toggle with Tailwind CSS
</h1>
<p className="mb-4">
Click the moon or sun icon in the top right corner to switch themes.
</p>
<p>
This example demonstrates how to implement a dark mode toggle in a
Next.js application using Tailwind CSS.
</p>
</div>
);
}
The text will automatically adapt to the theme because of the styles we've set in the layout.
Improving User Experience
To enhance the user experience, ensure that theme preferences are persisted and that the theme toggle is accessible. The ThemeToggle
component already handles persisting the user's preference in local storage.
You can also add a smooth transition between themes by adding the following CSS to your globals.css
:
html {
transition: background-color 0.5s, color 0.5s;
}
Automatically Detecting System Theme
The useEffect
hook in the ThemeToggle
component checks the user's system theme using the prefers-color-scheme
media query. This ensures that your application respects the user's system preferences on the first visit.
Final Thoughts
Implementing a dark mode toggle enhances the user experience by providing flexibility and accessibility. With Next.js and Tailwind CSS, adding this feature is straightforward and efficient.
You can further customize the theme toggle button, add animations, or even integrate a theme provider for more complex applications.
Additional Resources
Happy coding!