thumbnail

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

The benefits of implementing a dark mode toggle in a web application are numerous. It can help reduce eye strain, improve readability, and even save battery life on mobile devices. The trend towards dark mode has been growing in popularity, and it's no surprise that users are now expecting it as a standard feature in their favorite applications.

Next.js is a React framework that provides server-side rendering, making it easier to create performant and scalable web applications. Tailwind CSS is a utility-first CSS framework that allows for quick and easy styling of web applications.

In this tutorial, we will be using Next.js and Tailwind CSS to create a dark mode toggle for our web application.

Setting up the Project

To get started, we need to install both Next.js and Tailwind CSS. We can install Next.js by running the following command in our terminal:

    npx create-next-app my-app

Once Next.js is installed, we can install Tailwind CSS by running the following command:

npm install tailwindcss

After installing Tailwind CSS, we need to create the basic structure of our application. We can do this by creating a new file called index.js in the pages directory of our project.

In this file, we can add some basic HTML to display our content:

    <!DOCTYPE html>
    <html>
      <head>
        <title>Dark Mode Toggle</title>
      </head>
      <body>
        <div class="container mx-auto py-4">
          <h1 class="text-4xl font-bold mb-4">Welcome to my Dark Mode Toggle!</h1>
          <p class="text-lg">Click the button below to switch between light and dark mode.</p>
          <button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
            Toggle Theme
          </button>
        </div>
      </body>
    </html>

We can then add some basic styling to our application using Tailwind CSS. We can do this by creating a new file called styles.css in the styles directory of our project.

In this file, we can add the following code to apply some basic styles to our application:

    @tailwind base;
    @tailwind components;
    @tailwind utilities;

    body {
      background-color: #f7fafc;
    .container {
      max-width: 800px;

Implementing the Dark Mode Toggle

Now that our basic application structure and styling are complete, we can move on to implementing the dark mode toggle functionality.

To do this, we need to create a state variable to track the user's preferred theme. We can do this by adding the following code to our index.js file:

    import { useState from "react";

    export default function Home() {
      const [theme, setTheme] = useState("light");

      return (
        <div className={theme === "light" ? "bg-white" : "bg-gray-800      <div className="container mx-auto py-4">
            <h1 className="text-4xl font-bold mb-4">Welcome to my Dark Mode Toggle!</h1>
            <p className="text-lg">Click the button below to switch between light and dark mode.</p>
            <button
              className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
              onClick={() => setTheme(theme === "light" ? "dark" : "light        >
              Toggle Theme
            </button>
          </div>
        </div>
      );

In this code, we are using the useState hook from React to create a state variable called theme. The default value of theme is set to "light".

We are also using a ternary operator to conditionally apply a background color to our application based on the user's preferred theme. If the user has selected the light theme, we apply a white background color. If the user has selected the dark theme, we apply a dark gray background color.

We are also using an onClick event handler to toggle the user's preferred theme between light and dark.

Improving the User Experience

Now that we have implemented the basic functionality of our dark mode toggle, we can improve the user experience by adding some additional features.

First, we can persist the user's theme preference using localStorage. We can do this by adding the following code to our index.js file:

    import { useEffect, useState from "react";

    export default function Home() {
      const [theme, setTheme] = useState("light");

      useEffect(() => {
        const savedTheme = localStorage.getItem("theme");
        if (savedTheme) {
          setTheme(savedTheme);
         []);

      useEffect(() => {
        localStorage.setItem("theme", theme);
      [theme]);

      return (
        <div className={theme === "light" ? "bg-white" : "bg-gray-800      <div className="container mx-auto py-4">
            <h1 className="text-4xl font-bold mb-4">Welcome to my Dark Mode Toggle!</h1>
            <p className="text-lg">Click the button below to switch between light and dark mode.</p>
            <button
              className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
              onClick={() => setTheme(theme === "light" ? "dark" : "light        >
              Toggle Theme
            </button>
          </div>
        </div>
      );

In this code, we are using the useEffect hook from React to load the user's preferred theme from localStorage when the component mounts. We are also using another useEffect hook to save the user's preferred theme to localStorage whenever it changes.

Next, we can add some animations to our toggle button to enhance user feedback. We can do this by adding the following code to our styles.css file:

    @tailwind base;
    @tailwind components;
    @tailwind utilities;

    body {
      background-color: #f7fafc;
    .container {
      max-width: 800px;
    .theme-toggle {
      position: fixed;
      bottom: 2rem;
      right: 2rem;
    .theme-toggle-button {
      width: 60px;
      height: 30px;
      border-radius: 15px;
      position: relative;
    .theme-toggle-button::before {
      content: "";
      width: 30px;
      height: 30px;
      border-radius: 50%;
      background-color: #fff;
      position: absolute;
      top: 0;
      left: ${({ theme => (theme === "light" ? "0" : "30px")  transition: all .2s ease-in-out;
    .theme-toggle-button::after {
      content: "";
      width: 30px;
      height: 30px;
      border-radius: 50%;
      background-color: #000;
      position: absolute;
      top: 0;
      right: ${({ theme => (theme === "light" ? "0" : "30px")  transition: all .2s ease-in-out;
    .theme-toggle-button:hover::before {
      transform: scale(1.2);
    .theme-toggle-button:hover::after {
      transform: scale(1.2);

In this code, we are using CSS to create a toggle button with two states - light and dark. We are also using CSS transitions to animate the button when it is hovered over.

Finally, we can implement a media query to automatically switch between light and dark themes based on the user's device settings. We can do this by adding the following code to our styles.css file:

    @tailwind base;
    @tailwind components;
    @tailwind utilities;

    @media (prefers-color-scheme: dark) {
      body {
        background-color: #1a202c;
       .text-gray-800 {
        color: #fff;
       }
    }

In this code, we are using a media query to check for the user's preferred color scheme. If the user has selected a dark color scheme, we apply a dark background color and change the text color to white.

Conclusion

Summary: We've covered creating a dark mode toggle in Next.js and Tailwind CSS, including project setup, implementing toggle functionality, enhancing UX with localStorage and animations, and auto-switching themes based on device settings.

By implementing a dark mode toggle in your web application, you can improve the user experience and stay up-to-date with current design trends. With Next.js and Tailwind CSS, creating a dark mode toggle is quick and easy.

If you want to further customize and improve the toggle functionality, you can explore the documentation for Next.js and Tailwind CSS to learn more about their capabilities.

Author image

posted by Manu Arora

Need a website that stands out? Let's talk

We craft websites that can help you grow your business. You can trust us, I mean, you saw the testimonials right?

John Shahawy
Henrik Söderlund
John Ferry
Meru Gokhale
Georg Weingartner
Jonathan Barshop
Ray Thai