DEV Community

Cover image for How To Implement Dark/Light Themes in Next.js (React js) with Tailwind CSS

How To Implement Dark/Light Themes in Next.js (React js) with Tailwind CSS

Having an application or a website that enables users to choose themes is really nice and awesome in this modern day web. These days, people spend most of their time online and they are really hurting their eyes, providing such feature will improve the user experience.

In this article, we are going to discus how to build a Next js application that will enable users to choose between light and dark themes using Tailwind CSS and make it to be persistent.

Prerequisites you need to understand this article

1.Basic knowledge of React or Next js.
2.Basic understanding of javascript.
3.You must have Node js installed on your computer (for your React or 4.Next js application to run)
5.And finally, a web browser like Google Chrome.

Let`s install Next js

We have to install the latest version of Next js by running this command in our terminal.

npx create-next-app@latest

You will see some questions, asking you to choose what you would like to install along side with Next js. Make sure that you install Tailwind CSS through this way or you can also go to the official website of Tailwind CSS and read the documentation to install it manually. You can use your arrow keys to choose what you want to install and then click enter to select it.

Image description

Let`s start coding

We need to modify the config file of our Tailwind CSS with a special property value so that we can easily change theme of our application. We have to add this darkMode: “class” in the config file.

import type { Config } from "tailwindcss";

const config: Config = {
  content: [
    "./pages/**/*.{js,ts,jsx,tsx,mdx}",
    "./components/**/*.{js,ts,jsx,tsx,mdx}",
    "./app/**/*.{js,ts,jsx,tsx,mdx}",
  ],
  darkMode: "class",
  theme: {
    extend: {
      backgroundImage: {
        "gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
        "gradient-conic":
          "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
      },
    },
  },
  plugins: [],
};
export default config;
Enter fullscreen mode Exit fullscreen mode

Here, we are checking if the app is done loading, then we will get the theme that the user might have selected previously from the local storage. If the user haven`t selected any theme previously, then we will set the theme to light.


const [theme, setTheme] = useState<any>(
typeof window !== "undefined" ? localStorage.getItem("theme") : "light"
);

Here we are using useffect to select the theme automatically once the page is done loading. We are checking the value in the useState if it is dark theme, once it`s dark theme, we add the dark class to our application which will give it a dark theme effect through the help of Tailwind CSS. We also store the latest value or theme to the local storage and also trigger the function whenever a user updates the theme.

useEffect(() => {
    if (theme === "dark") {
      document.documentElement.classList.add("dark");
    } else {
      document.documentElement.classList.remove("dark");
    }
    localStorage.setItem("theme", theme);
  }, [theme]);
Enter fullscreen mode Exit fullscreen mode

This function helps users to switch themes. Here we are using ternary operator to check the value of the theme to update it accordingly. If the value of the theme is dark, we will then update the value of the theme to light, vice versa.

const toggleTheme = () => {
    setTheme(theme === "dark" ? "light" : "dark");
  };
Enter fullscreen mode Exit fullscreen mode

Here we are using the dark class in Tailwind CSS to give each element a different kind of style if the application is in dark theme, you can clearly see that you can hide some elements if you don`t want them to be visible in the dark theme.

`
import { useState, useEffect } from "react";
import DarkModeIcon from "@mui/icons-material/DarkMode";
import WbSunnyIcon from "@mui/icons-material/WbSunny";

export default function Home() {
const [theme, setTheme] = useState(
typeof window !== "undefined" ? localStorage.getItem("theme") : "light"
);

useEffect(() => {
if (theme === "dark") {
document.documentElement.classList.add("dark");
} else {
document.documentElement.classList.remove("dark");
}
localStorage.setItem("theme", theme);
}, [theme]);

const toggleTheme = () => {
setTheme(theme === "dark" ? "light" : "dark");
};
return (


{/* logo */}

    <svg
      id="logo-88"
      width="40"
      height="41"
      viewBox="0 0 40 41"
      fill="none"
      xmlns="http://www.w3.org/2000/svg"
    >
      <path
        className="ccustom"
        fill-rule="evenodd"
        clip-rule="evenodd"
        d="M13.7146 0.516113C11.4582 0.516113 9.2943 1.41245 7.69881 3.00794L0 10.7067V14.2307C0 16.7204 1.06944 18.9603 2.77401 20.5161C1.06944 22.0719 0 24.3118 0 26.8015V30.3255L7.69881 38.0243C9.2943 39.6198 11.4582 40.5161 13.7146 40.5161C16.2043 40.5161 18.4442 39.4467 20 37.7421C21.5558 39.4467 23.7957 40.5161 26.2854 40.5161C28.5418 40.5161 30.7057 39.6198 32.3012 38.0243L40 30.3255V26.8015C40 24.3118 38.9306 22.0719 37.226 20.5161C38.9306 18.9603 40 16.7204 40 14.2307V10.7067L32.3012 3.00794C30.7057 1.41245 28.5418 0.516113 26.2854 0.516113C23.7957 0.516113 21.5558 1.58555 20 3.29012C18.4442 1.58555 16.2043 0.516113 13.7146 0.516113ZM25.7588 20.5161C25.6629 20.4286 25.5688 20.3387 25.4766 20.2465L20 14.7699L14.5234 20.2465C14.4312 20.3387 14.3371 20.4286 14.2412 20.5161C14.3371 20.6036 14.4312 20.6935 14.5234 20.7857L20 26.2623L25.4766 20.7857C25.5688 20.6935 25.6629 20.6036 25.7588 20.5161ZM22.2222 30.3255L22.2222 32.0085C22.2222 34.2525 24.0414 36.0717 26.2854 36.0717C27.363 36.0717 28.3965 35.6436 29.1585 34.8816L35.5556 28.4845V26.8015C35.5556 24.5575 33.7364 22.7383 31.4924 22.7383C30.4148 22.7383 29.3813 23.1664 28.6193 23.9284L22.2222 30.3255ZM17.7778 30.3255L11.3807 23.9284C10.6187 23.1664 9.58524 22.7383 8.50762 22.7383C6.26359 22.7383 4.44444 24.5575 4.44444 26.8015V28.4845L10.8415 34.8816C11.6035 35.6436 12.637 36.0717 13.7146 36.0717C15.9586 36.0717 17.7778 34.2525 17.7778 32.0085V30.3255ZM17.7778 9.02373V10.7067L11.3807 17.1038C10.6187 17.8658 9.58524 18.2939 8.50762 18.2939C6.26359 18.2939 4.44444 16.4747 4.44444 14.2307V12.5477L10.8415 6.15063C11.6035 5.38864 12.637 4.96056 13.7146 4.96056C15.9586 4.96056 17.7778 6.7797 17.7778 9.02373ZM28.6193 17.1038L22.2222 10.7067L22.2222 9.02373C22.2222 6.7797 24.0414 4.96056 26.2854 4.96056C27.363 4.96056 28.3965 5.38864 29.1585 6.15063L35.5556 12.5477V14.2307C35.5556 16.4747 33.7364 18.2939 31.4924 18.2939C30.4148 18.2939 29.3813 17.8658 28.6193 17.1038Z"
        fill="#FF630B"
      ></path>
    </svg>

    {/* links */}
    <ul className="flex items-center justify-between gap-x-3">
      <li>Home</li>
      <li>About</li>
      <li>Contact</li>
    </ul>
    {/* toggle */}
    <div className="cursor-pointer" onClick={toggleTheme}>
      <DarkModeIcon className=" dark:hidden" />
      {/* sun */}
      <WbSunnyIcon className="hidden dark:block" />
    </div>
  </nav>

  {/* theme con */}
  <div className="flex items-center justify-center w-[500px] mt-[20px] h-[500px] bg-red-600 dark:bg-black">
    {/* text con */}
    {/* <div> */}
    <h6 className="  text-center dark:hidden">Light theme</h6>
    <h6 className=" hidden text-center dark:block dark:text-white">
      Dark theme
    </h6>
    {/* </div> */}
  </div>
</main>
Enter fullscreen mode Exit fullscreen mode

);
}
`

The result

light and dark theme demo

Conclusion

Applications with dark and light themes makes it easier for users to have good user experience, giving them the flexibility to choose any theme of their choice which will make them to stay longer in your application leading to increase in sales.

We can achieve this easily with Nextjs, Tailwind CSS and the browser`s local storage to make it persistent.

Now with your newly acquired knowledge, go and make the web a better place.

Happy coding 😊!

Top comments (0)