This is a component I made for my blog. It uses next-themes, Tailwind CSS, and HeadlessUI.
It lets you switch between light and dark themes or use the system preference.
Clone the repository
git clone git@github.com:erikJonsberg/dark-mode-selector.gitNavigate to the project directory
cd dark-mode-selectorInstall dependencies
npm iRun the development server
npm run devIf you want to use this component in your own project, you need to set up next-themes.
First install next-themes
npm i next-themesIn tailwind.config.ts add darkMode: "selector"
import type { Config } from 'tailwindcss';
const config: Config = {
darkMode: 'selector',
content: [
'./src/pages/**/*.{js,ts,jsx,tsx,mdx}',
'./src/components/**/*.{js,ts,jsx,tsx,mdx}',
'./src/app/**/*.{js,ts,jsx,tsx,mdx}',
],
theme: {},
plugins: [],
};
export default config;Create a directory called providers and, inside it, create a file called ThemeProvider.tsx. Add the following code:
"use client";
import { ThemeProvider } from "next-themes";
interface ProviderProps {
children: React.ReactNode;
}
export function Provider({ children }: ProviderProps) {
return (
<ThemeProvider attribute='class'>
{children}
</ThemeProvider>;
)
}In layout.tsx, import the provider function and wrap the {children} inside the body tag. Add suppressHydrationWarning to the html tag. Your layout.tsx file should now look like this:
import type { Metadata } from 'next';
import { Provider } from '../providers/ThemeProvider';
import { Inter } from 'next/font/google';
import './globals.css';
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}>
<Provider>{children}</Provider>
</body>
</html>
);
}That's it!! 👏
For more information, check out the documentation for all the packages used in this component.