Dark Mode in Next.js: A Step-by-Step Guide
Are you looking to add a cool dark mode to your Next.js project? You're in luck because I've got a step-by-step guide to do just that using next-themes! Let's dive in.
Setting Up next-themes
First, we need to install next-themes. Run npm install next-themes in your project directory. This handy package helps manage theme switching seamlessly.
Configuring next-themes
'use client';
import { ThemeProvider } from 'next-themes';
import { ReactNode } from 'react';
export function Providers({ children }: { children: ReactNode }) {
return <ThemeProvider attribute="class">{children}</ThemeProvider>;
}
Setting Up RootLayout
import { Providers } from './providers';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en" suppressHydrationWarning>
<body>
<Providers>
<main>{children}</main>
</Providers>
</body>
</html>
);
}
suppressHydrationWarning is used in Next.js with next-themes to prevent warnings about discrepancies between server and client renders due to theme changes, ensuring smooth hydration despite theme preferences.
I am going to use TailwindCSS to style, so let's set it up!
import type { Config } from "tailwindcss";
const config: Config = {
content: [
"./src/components/**/*.{js,ts,jsx,tsx,mdx}",
"./src/app/**/*.{js,ts,jsx,tsx,mdx}",
],
theme: {},
},
darkMode: "class",
};
export default config;
Create a Theme Switcher
'use client';
import { useTheme } from 'next-themes';
import React, { useEffect, useState } from 'react';
const ThemeToggleButton = () => {
const { theme, setTheme } = useTheme();
const [mounted, setIsMounted] = useState(false);
useEffect(() => {
setIsMounted(true);
}, []);
if (!mounted) return null;
return (
<button
aria-label="Theme Switcher"
onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}>
Toogle Theme{' '}
</button>
);
};
export default ThemeToggleButton;
We need the mounted state to make sure that component did mount on a client side and we can use hooks
Styling for Dark and Light Mode
export default function Home() {
return (
<section className="mb-20 h-screen">
<ThemeSwitcher />
<article className="bg-white dark:bg-gray-900 rounded-md">
<h2 className="text-gray-900 dark:text-white">Easy Dark theme</h2>
<p className="text-gray-500 dark:text-slate-300">Next.js + next-themes</p>
</article>
</section>
);
}
And there you have it! A simple yet effective way to add dark mode to your Next.js app with next-themes. Happy coding! 🌒🌓🌔