TIL: @pacocoursey next-themes
. I've been pretty happy using @tailwindCSS and letting the system render the right theme for the user, but if you do want to add UI controls. Give this no-brainer a shot, here's how I did mine.
Set the provider and attribute to display the active theme as a class. This will enable all dark
classes present in the HTML tree. Don't forget to declare this in your @tailwindCSS config file: module.exports = { darkMode: 'class' }
:
import { ThemeProvider } from "next-themes";
import type { AppProps } from "next/app";
function MyApp({ Component, pageProps }: AppProps) {
return (
<ThemeProvider attribute="class">
<Component {...pageProps} />
</ThemeProvider>
);
}
To consume and toggle the UI, use their useTheme
hook. To avoid hydration errors, return a loading state of your choice until fully mounted:
import { useState, useEffect } from "react";
import { useTheme } from "next-themes";
import { SunIcon, MoonIcon } from "@heroicons/react/outline";
export default function ThemeToggler() {
const { resolvedTheme, setTheme } = useTheme();
const [mounted, setMounted] = useState(false);
useEffect(() => { setMounted(true) }, []);
if (!mounted) return <></>;
return (
<button
onClick={() => {
setTheme(resolvedTheme === "dark" ? "light" : "dark");
}}
>
{resolvedTheme === "dark" ? <SunIcon /> : <MoonIcon />}
</button>
);
}
It is that simple. It has 74,528 weekly npm downloads and if it's good enough for @leeerob, it's good for me too. Get creative with your loading state and toggle button (or not && KISS). Check out their next-themes
GH repo for more info.
Originally published: No-brainer Dark Mode for Next.js
Top comments (1)
real live saver, thanks for the post!