Dark Mode
Quickly set up dark mode using next-themes
.
Install the next-themes package.
pnpm add next-themes
Edit your root layout.tsx
file to include the ThemeProvider
component.
import "~/styles/globals.css";
import { ThemeProvider } from "next-themes";
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en" suppressHydrationWarning>
<head />
<body>
<ThemeProvider
defaultTheme="dark"
attribute="class"
disableTransitionOnChange
>
<Header />
<main>{children}</main>
</ThemeProvider>
</body>
</html>
);
}
Add your theme toggle component. Mine looks like this.
import { useTheme } from "next-themes";
import { MoonIcon, SunIcon } from "@radix-ui/react-icons";
import { Button } from "~/components/ui/Button";
export default function ThemeToggle() {
const { theme, setTheme } = useTheme();
const Icon = theme === "light" ? SunIcon : MoonIcon;
return (
<Button
onClick={()=> setTheme(theme= "light" ? "dark" : "light")}
variant="ghost"
subject="icon"
size="xs"
className="text-muted-foreground [&_svg]:size-4.5"
>
<Icon />
</Button>
);
}
Import the ThemeToggle
using next/dynamic
. Learn why you need to do this here.
import { dynamic } from "next/dynamic";
const ThemeToggle = dynamic(() => import("./ThemeToggle"), {
ssr: false,
loading: () => <div className="size-8" />,
});
export default function Header() {
return (
<>
...
<ThemeToggle />
...
</>
)
}