Implement Tailwind CSS Dark Mode in a Next.js Project

Implement Tailwind CSS Dark Mode in a Next.js Project

Learn to implement Tailwind CSS Dark Mode in your Next.js applications in this easy-to-follow tutorial

Introduction:

We can argue that web accessibility, i.e., aiming to make digital content available and usable to all individuals, including those with certain disabilities, is an important part of web design and development.

One significant enhancement in the recent web design trends which improves web accessibility is the implementation of dark mode. Dark mode has become a popular feature in web design, offering users a more comfortable browsing experience in low-light conditions and reducing eye strain.

In this blog, I'll walk you through the steps of implementing dark mode in your Next.js projects using Tailwind CSS and the next-themes library.

Prerequisites:

Before you begin, ensure you have the following prerequisites in place:

  1. Node.js and npm installed on your computer.

  2. Basic knowledge of Next.js and Tailwind CSS.

Implement Dark Mode:

  • Create a Next.js Project:

If you haven't already, create a new Next.js project. You can do so by opening any terminal of your choice, and running the following command:

npx create-next-app@latest

You'll be prompted to configure the project's name and settings. Say yes to using Tailwind CSS and an App Router.

For more options regarding installation, you can visit the official documentation here.

Open your newly created Next.js project in VS Code. You'll see a project structure similar to this:

- app
    - favicon.ico
    - globals.css
    - page.js
    - layout.js
- node_modules
- public
- .eslintrc.json
- .gitignore
- jsconfig.json
- next.config.js
- package-lock.json
- package.json
- postcss.config.js
- README.md
- tailwind.config.js
  • Configure Tailwind Settings:

Open the tailwind.config.js file, and modify it to include darkMode as such:

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    './pages/**/*.{js,ts,jsx,tsx,mdx}',
    './components/**/*.{js,ts,jsx,tsx,mdx}',
    './app/**/*.{js,ts,jsx,tsx,mdx}',
  ],
  darkMode: ["class"],
  theme: {
    extend: {
    }
  },
  plugins: [],
}
  • Install next-themes Library:

    In the terminal, run the following command to install the next-themes library inside your project:

$ npm install next-themes
  • Create a Theme Provider:

    Inside your app folder, create a new file by the name of theme-provider.js and paste the following code into it:

"use client";
import React from "react";
import { ThemeProvider as NextThemesProvider } from "next-themes";

export function ThemeProvider({ children, ...props }) {
  return <NextThemesProvider {...props}>{children}</NextThemesProvider>;
}

This code defines a ThemeProvider component that leverages the next-themes library's NextThemesProvider to provide theming capabilities to its child components. The ThemeProvider component allows us to control the theme of our Next.js application and customize its appearance.

  • Wrap the App inside Theme Provider:

Open the layout.js file present inside your app folder, import the ThemeProvider component that we defined above and wrap it around the children as such:

import "../styles/globals.css";
import { ThemeProvider } from "./theme-provider";

const RootLayout = ({children}) => {
    return (
        <html lang="en">
            <body>
                <ThemeProvider attribute="class">
                    {children}
                </ThemeProvider>
            </body>
        </html>
    )
};

export default RootLayout;

Wrapping the children prop inside the ThemeProvider will enable the usage of theme functionality in the project.

  • Create a Theme Toggle Button:

Create a components folder in the root directory of your project. Create a ToggleThemeButton.js file inside it. Paste the following code into it:

import { useState, useEffect } from "react";
import { useTheme } from "next-themes";

export const ToggleThemeButton = () => {
    const [mounted, setMounted] = useState(false);
    const { theme, setTheme } = useTheme();

    useEffect(() => {
        setMounted(true);
      }, []);

      if (!mounted) {
        return null;
      }

  return (
    <button
      className="p-2 text-black dark:text-white border-gray-600 dark:border-gray-200 bg-white dark:bg-gray-900"
      onClick={() => setTheme(theme === "dark" ? "light" : "dark")}
    >
      {theme === "light" ? "Dark" : "Light"}
    </button>
  )
}

You can import this component anywhere or create theme toggling buttons following the same logic inside other components, and toggle the theme of your project.

You'll be able to design components for the dark mode using a dark: prefix, i.e.,

<div className="bg-white dark:bg-gray-900"></div>

Conclusion:

By following the steps outlined in this blog, you can enable dark mode functionality in your Next.js project and provide a more comfortable and visually appealing experience for your users, all while keeping your code clean and maintainable. Dark mode isn't just a trend—it's a valuable accessibility feature that can improve the usability of your web application.

Thanks for reading!