Create a dark mode theme switch in Nextjs 13

How to add dark theme capability in Nextjs app using next-themes


Creating React powered JavaScript application using Nextjs is easy. This example utilizes the experimental features of Nextjs 13.

I assume that you have Nextjs project ready in hand, otherwise follow the Next 13 app setup guide.

Theming the App

For theming I have been using Tailwind and for dark theme we can use a minimal library, next-themes.

Install the library using yarn or npm

$ npm install next-themes
# or
$ yarn add next-themes 

Theme Provider

First up all we need a theme provider component to pass the theme to all the component in app (experimental feature appDir of Nextjs 13) folder.

'use client'

import { ThemeProvider } from 'next-themes'

export function Providers({ children }) {
  return <ThemeProvider attribute="class">{children}</ThemeProvider>
}

Here we used the ThemeProvider of next-themes for applying the theme.

Note that we should mark the component as client component.

In Nextjs appDir feature will set all component sever side components by default.

Tailwind configuration

When we using Next-Theme with Tailwind we may need to use the Tailwind dark theme, so we can use TW class.

 /** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./app/**/*.{js,ts,jsx,tsx}",
    "./pages/**/*.{js,ts,jsx,tsx}",
    "./components/**/*.{js,ts,jsx,tsx}",
 
    // Or if using `src` directory:
    "./src/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
  darkMode: 'class'
}

Root Layout

In the root layout we can wrap the body of the app with the Provider.

Theme Switcher

We need a component for switching between Light and Dark theme.

'use client'
import { useState, useEffect } from "react";
import { useTheme } from "next-themes";
import { SunIcon } from "@heroicons/react/outline";

const ThemeSwitch = () => {
  const [mounted, setMounted] = useState(false);
  const { theme, setTheme } = useTheme();
  // useEffect only runs on the client, so now we can safely show the UI
  useEffect(() => {
    setMounted(true);
  }, []);

  if (!mounted) {
    return null;
  }
  

  return (
    <div className="inline-flex items-center">
      <SunIcon className="w-4 h-4 mr-2" />
      <select
        name="themeSwitch"
        value={theme}
        onChange={e =>setTheme(e.target.value)}>
        <option value="system">System</option>
        <option value="dark">Dark</option>
        <option value="light">Light</option>
      </select>
    </div>
  );
};

Using the useTheme hook and setTheme method we can change the theme, easily from any component.

Author: Manoj

Developer and a self-learner, love to work with Reactjs, Angular, Node, Python and C#.Net

One thought on “Create a dark mode theme switch in Nextjs 13”

  1. Dark/Light is easy… It would be nice a tutorial for Next13, Tailwind, Next-Themes and 3 distinct themes…

    Like

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.