DEV Community

Cover image for How To Add Dark Mode Toggle in ReactJS + TailwindCSS + DaisyUI ⚛️🌼
Kunal Ukey
Kunal Ukey

Posted on

How To Add Dark Mode Toggle in ReactJS + TailwindCSS + DaisyUI ⚛️🌼

Introduction:

In this tutorial, we will learn how to add a dark mode toggle with local storage persistence to a ReactJS + TailwindCSS + DaisyUI project. We will begin by setting up the project and installing the necessary dependencies. Next, we will create a Navbar and Hero component using DaisyUI's pre-built components. Finally, we will implement a dark mode toggle using DaisyUI's help and by updating the custom attribute in the HTML tag to add local storage persistence to it.

Prerequisites:

Before we get started, you need to have the following tools and technologies installed on your machine:

  • NodeJS
  • Code Editor

Initiate ReactJS project

Let's start by creating a new Reactjs project using the create-react-app command.

npx create-react-app dark-mode-toggle
cd dark-mode-toggle
Enter fullscreen mode Exit fullscreen mode

Then remove the unnecessary files and code from the src directory.

Installing and Configuring TailwindCSS

To install TailwindCSS, run the following command:

npm install -D tailwindcss
Enter fullscreen mode Exit fullscreen mode

Then create a new file called tailwind.config.js by running the following command:

npx tailwindcss init
Enter fullscreen mode Exit fullscreen mode

In the tailwind.config.js file, add the following code to it:

module.exports = {
  content: [
    "./src/**/*.{js,jsx,ts,tsx}",
  ],

  theme: {
    extend: {},
  },
  plugins: [],
}
Enter fullscreen mode Exit fullscreen mode

In your src/index.css file, add the following directives:

@tailwind base;
@tailwind components;
@tailwind utilities;
Enter fullscreen mode Exit fullscreen mode

Installing and Configuring DaisyUI

Now that we've set up TailwindCSS, let's install DaisyUI. DaisyUI is a collection of ready-to-use UI components designed to work seamlessly with TailwindCSS.

To install DaisyUI, run the following command in your project directory:

npm install daisyui
Enter fullscreen mode Exit fullscreen mode

After the installation is complete, we need to configure DaisyUI with TailwindCSS.

Open the tailwind.config.js file and add the following code at the end of the plugins array:

plugins: [require('daisyui')],
Enter fullscreen mode Exit fullscreen mode

Now we also need to add the daisyUI themes so that we can switch between them.

  daisyui: {
    themes: ["light", "dark"],
  },
Enter fullscreen mode Exit fullscreen mode

The whole code in our tailwind.config.js file would look something like this:

module.exports = {
  content: [
    "./src/**/*.{js,jsx,ts,tsx}",
  ],

  theme: {
    extend: {},
  },
  plugins: [require("daisyui")],
  daisyui: {
    themes: ["light", "dark"],
  },
}
Enter fullscreen mode Exit fullscreen mode

Navbar component

Now create an Navbar.js file inside the src/components folder and add the following code to it:

import { useState, useEffect } from "react";

// assets
import logo from "../assets/om-logo.png";
import sun from "../assets/sun.svg";
import moon from "../assets/moon.svg";

const Navbar = () => {
  return (
    <div className="navbar bg-base-100 shadow-lg px-4 sm:px-8">
      <div className="flex-1">
        <img src={logo} alt="OM" className="btn btn-ghost p-0" />
        <h1 className="text-lg font-bold mx-4">Your Website</h1>
      </div>
      <div className="flex-none">
        {/* Toggle button here */}
        <button className="btn btn-square btn-ghost">
          <label className="swap swap-rotate w-12 h-12">
            <input type="checkbox" />
            {/* light theme sun image */}
            <img src={sun} alt="light" className="w-8 h-8 swap-on" />
            {/* dark theme moon image */}
            <img src={moon} alt="dark" className="w-8 h-8 swap-off" />
          </label>
        </button>
      </div>
    </div>
  );
};
export default Navbar;
Enter fullscreen mode Exit fullscreen mode

Hero component (Optional)

To add some content to our single page, let's create another component called Hero.js inside the src/components folder and add the following code it:


const Hero = () => {
  return (
    <div className="hero min-h-full h-full pt-[20%]">
      <div className="hero-content text-center">
        <div className="max-w-md">
          <h1 className="text-5xl font-bold">Your Awesome Website!</h1>
          <p className="py-6">
            Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s.
          </p>
          <button className="btn btn-primary">
            Checkout
          </button>
        </div>
      </div>
    </div>
  );
};
export default Hero;
Enter fullscreen mode Exit fullscreen mode

Adding Navbar and Hero components to App.js

Now we are ready to show our components in our single page by adding them to the App.js component as:

import Navbar from "./components/Navbar";
import Hero from "./components/Hero";

function App() {
  return (
    <div className="h-full min-h-full">
      <Navbar />
      <Hero />
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Implementing Dark Mode Toggle functionality

Towards the end, we have to toggle the dark/theme when we click on the toggle button from the Navbar component. So, add the following code to the Navbar.js component:

import { useState, useEffect } from "react";

// assets
import logo from "../assets/om-logo.png";
import sun from "../assets/sun.svg";
import moon from "../assets/moon.svg";

const Navbar = () => {
  // use theme from local storage if available or set light theme
  const [theme, setTheme] = useState(
    localStorage.getItem("theme") ? localStorage.getItem("theme") : "light"
  );

  // update state on toggle
  const handleToggle = (e) => {
    if (e.target.checked) {
      setTheme("dark");
    } else {
      setTheme("light");
    }
  };

  // set theme state in localstorage on mount & also update localstorage on state change
  useEffect(() => {
    localStorage.setItem("theme", theme);
    const localTheme = localStorage.getItem("theme");
    // add custom data-theme attribute to html tag required to update theme using DaisyUI
    document.querySelector("html").setAttribute("data-theme", localTheme);
  }, [theme]);

  return (
    <div className="navbar bg-base-100 shadow-lg px-4 sm:px-8">
      <div className="flex-1">
        <img src={logo} alt="OM" className="btn btn-ghost p-0" />
        <h1 className="text-lg font-bold mx-4">Your Website</h1>
      </div>
      <div className="flex-none">
        {/* Toggle button here */}
        <button className="btn btn-square btn-ghost">
          <label className="swap swap-rotate w-12 h-12">
            <input
              type="checkbox"
              onChange={handleToggle}
              // show toggle image based on localstorage theme
              checked={theme === "light" ? false : true}
            />
            {/* light theme sun image */}
            <img src={sun} alt="light" className="w-8 h-8 swap-on" />
            {/* dark theme moon image */}
            <img src={moon} alt="dark" className="w-8 h-8 swap-off" />
          </label>
        </button>
      </div>
    </div>
  );
};
export default Navbar;
Enter fullscreen mode Exit fullscreen mode

Conclusion:

Congratulations! You've successfully added a dark mode toggle to your ReactJS application using Tailwind CSS and daisyUI. Now your users can enjoy the flexibility of choosing their preferred theme for a better user experience.

Thanks for following along, and happy coding!❤️

Top comments (6)

Collapse
 
joepreludian profile image
Jonhnatha Trigueiro

Thank you a Mil! Worked like a charm.
If I would suggest you a small improvement about the line related to this code excerpt...

    document.querySelector("html").setAttribute("data-theme", localTheme);
Enter fullscreen mode Exit fullscreen mode

I would use this one instead;

    document.documentElement.setAttribute("data-theme", localTheme);
Enter fullscreen mode Exit fullscreen mode

Thank you!

Collapse
 
taufiqtoki profile image
Mohammad Taufiqul Islam Toki

Thank you so much,, it worked

Collapse
 
hyeonho2010 profile image
hyeonho

I respect you.

Collapse
 
nahidestes profile image
Nahid Estes

Thank You

Collapse
 
ragibshariar profile image
Syed Ragib Shariar

Thanks a ton. please make a video on how to set the theme on PC theme preferences like the Tailwind website.

Collapse
 
a4alif profile image
Alif Hasan Shah

Thank you so much.