Dark mode in Next.js

Next-themes provides a simplified way to integrate dark mode switching into your Next.js application.

Installation

Install next-themes

Start by installing next-themes:

npm install next-themes

Create a theme provider

Create a theme-provider.tsx file and paste the below code in it

"use client";

import * as React from "react";
import { ThemeProvider as NextThemesProvider } from "next-themes";
import { type ThemeProviderProps } from "next-themes/dist/types";

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

Add the provider

Wrap your application with the ThemeProvider component.

import { ThemeProvider } from "@/components/theme-provider";

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en" suppressHydrationWarning>
      <head />
      <body>
        <ThemeProvider enableSystem={true} attribute="class">
          {children}
        </ThemeProvider>
      </body>
    </html>
  );
}

Create a toggle

Create a toggle button to switch between light and dark themes.

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

import { MoonIcon, SunIcon } from "@astraicons/react/linear";
import { Button } from "@/app/common/astra-ui/button";

const ThemeButton = () => {
  const { theme, setTheme } = useTheme();

  return (
    <Button
      className="flex-shrink-0 p-2.5 ring-0 focus:ring-0 focus:border-none text-grayscale-textIcon-title"
      variant="ghost"
      size="md"
      onClick={() => setTheme(theme === "light" ? "dark" : "light")}
    >
      <SunIcon className="size-6 transition-all scale-100 rotate-0 dark:-rotate-90 dark:scale-0" />
      <MoonIcon className="absolute size-6 transition-all scale-0 rotate-90 dark:rotate-0 dark:scale-100" />
      <span className="sr-only">Toggle theme</span>
    </Button>
  );
};

export default ThemeButton;

Expand

Now you can use this switch in your application to toggle between light and dark themes.