Enabling Dark Mode and Light Mode Switch in Next.js 14.2 with Tailwind CSS

Enabling Dark Mode and Light Mode Switch in Next.js 14.2 with Tailwind CSS

Creating a dark mode/light mode switch is a common feature that enhances user experience by allowing users to switch between themes according to their preferences. In this article, we will use Next.js 14.2, Tailwind CSS, and the `next-themes` library to implement this feature. Let's dive into the step-by-step process.

Step 1: Set Up Next.js with Tailwind CSS

First, we need to set up a new Next.js project with Tailwind CSS. If you haven't already, install the necessary packages by running the following commands in your terminal:

npx create-next-app@latest my-next-app
cd my-next-app
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init        

or you can simply

npx create-next-app@latest

Then it will ask following questions , you can choose from there.

What is your project named?  my-next-app
Would you like to use TypeScript?  No / Yes
Would you like to use ESLint?  No / Yes
Would you like to use Tailwind CSS?  No / Yes
Would you like to use `src/` directory?  No / Yes
Would you like to use App Router? (recommended)  No / Yes
Would you like to customize the default import alias (@/*)?  No / Yes        

Next, configure Tailwind CSS by updating the `tailwind.config.ts` and `globals.css` files.

tailwind.config.ts:

import type { Config } from "tailwindcss";

const config: Config = {
  darkMode: 'class', // Enable dark mode with class strategy
  content: [
    "./pages/**/*.{js,ts,jsx,tsx,mdx}",
    "./components/**/*.{js,ts,jsx,tsx,mdx}",
    "./app/**/*.{js,ts,jsx,tsx,mdx}",
  ],
  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;        

`global.css`

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

@layer base {
  body {
    @apply dark:bg-slate-800 bg-gray-50;
  }
}        

These configurations set up Tailwind CSS to handle dark mode using class-based strategy and apply default background colors for both themes.

Next, install the required packages for icons and themes:

npm install react-icons next-themes        

Step 2: Create the Theme Provider

Next, create a file called provider.tsx in the app directory with the following code:

"use client"; 
import { ThemeProvider } from "next-themes"; 

export function Providers({ children }: 
{ children: React.ReactNode }) { 
return ( 
<ThemeProvider 
attribute="class" defaultTheme="system" enableSystem>
 {children} </ThemeProvider> 
);
 }        

This code sets up the theme provider using `next-themes`, enabling theme switching based on the system's preference by default.

Step 3: Wrap the App with the Provider

Now, we need to wrap our application with the theme provider. Open layout.tsx in the app directory and update it as follows:

import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import { Providers } from "./providers";

const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
  title: "Create Next App",
  description: "Generated by create next app",
};

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en" suppressHydrationWarning>
      <body className={inter.className}>
        <Providers>{children}</Providers>
      </body>
    </html>
  );
}        

This code ensures that the theme provider wraps the entire application, enabling theme switching functionality throughout the app.

Step 4: Create the Theme Switcher Component

Next, create a components directory and add a file called ThemeSwitcher.tsx with the following code:

"use client";

import { HiOutlineSun as SunIcon, HiOutlineMoon as MoonIcon } from "react-icons/hi";
import { useState, useEffect } from "react";
import { useTheme } from "next-themes";

export default function ThemeSwitch() {
  const [mounted, setMounted] = useState(false);
  const { systemTheme, theme, setTheme } = useTheme();
  const currentTheme = theme === "system" ? systemTheme : theme;

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

  if (!mounted) return <>...</>;

  if (currentTheme === "dark") {
    return <SunIcon className="h-6 w-6" onClick={() => setTheme("light")} />;
  }

  if (currentTheme === "light") {
    return (
      <MoonIcon className="h-6 w-6 text-gray-900" onClick={() => setTheme("dark")} />
    );
  }
}        

This component provides the UI for switching between light and dark modes. It uses icons from `react-icons` to display a sun or moon icon depending on the current theme.

Step 5: Integrate the Theme Switcher in the Home Page

Finally, import and use the ThemeSwitcher component in `page.tsx` in the app directory:

import ThemeSwitcher from "./components/ThemeSwitcher";

export default function Home() {
  return (
    <main>
      <div className="relative overflow-hidden">
        <div className="relative z-10">
          <div className="max-w-[85rem] mx-auto px-4 sm:px-6 lg:px-8 py-10 lg:py-16">
            <div className="max-w-2xl text-center mx-auto">
              <div className="mt-5 max-w-2xl items-center flex">
                <h1 className="block font-semibold text-gray-800 text-4xl md:text-5xl lg:text-6xl dark:text-neutral-200">
                  LOREM IPSUM PICSUM
                </h1>
                <ThemeSwitcher />
              </div>
              <div className="mt-5 max-w-3xl">
                <p className="text-lg text-gray-600 dark:text-neutral-400">
                  Sed ut perspiciatis unde omnis iste natus error sit voluptatem
                  accusantium doloremque laudantium, totam rem aperiam, eaque
                  ipsa quae ab illo inventore veritatis et quasi architecto
                  beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem
                  quia voluptas sit aspernatur aut odit aut fugit, sed quia
                  consequuntur magni dolores eos qui ratione voluptatem sequi
                  nesciunt. Neque porro quisquam est, qui dolorem ipsum quia
                  dolor sit amet, consectetur, adipisci velit, sed quia non
                  numquam eius modi tempora incidunt ut labore et dolore magnam
                  aliquam quaerat voluptatem.
                </p>
              </div>
            </div>
          </div>
        </div>
      </div>
    </main>
  );
}        

This integration adds the ThemeSwitcher component to the home page, allowing users to switch between dark and light modes.

Conclusion

In this article, we've walked through the steps to implement a dark mode/light mode switch in a Next.js application using Tailwind CSS and the next-themes library. By following these steps, you can enhance your application with a customizable theme switcher that improves user experience. Happy coding!

Here is the public repo the of the code.



Juliano Silva?

Fullstack Developer | Node.js | Typescript

2 个月

tks, I re-applied this template to scss

要查看或添加评论,请登录

Trilochan Satapathy的更多文章

社区洞察

其他会员也浏览了