next-themes is a cool package that provide an easy solution to managing your website theme. Today we're going to learn how to set up next-themes to work with Tailwind CSS
Prerequisite
- Already have some experience with Nextjs
- Already have some experience with Tailwind CSS
- Already have some experience with next-themes
Let's Get Started!
We need to install a Next app, Tailwind CSS and next-themes.
Create a next app
npx create-next-app theme-example
Install Tailwind CSS
npm i tailwindcss postcss autoprefixer -D
And finally next-themes
npm i next-themes
Setting up next-themes
inside the _app.js
file wrap Component
with the ThemeProvider
provided by next-themes.
Since we're using Tailwind CSS which uses class for styling, We need to pass attribute="class"
for ThemeProvider
to tell it we're using class to style the theme
import { ThemeProvider } from "next-themes";
function App({ Component, pageProps }) {
return (
<ThemeProvider attribute="class">
<Component {...pageProps} />
</ThemeProvider>
);
}
export default App;
Now we need to setup postcss and tailwind configuration for next-themes
Setting up postcss and Tailwind CSS
-
postcss
Create a
postcss.config.js file
file in the root directory with the following config:
// ./postcss.config.js
module.exports = {
plugins:{
tailwindcss: {},
autoprefixer: {}
}
};
-Tailwind CSS
Create a tailwindcss.config.js
file in the root directory with the following config:
Note the darkMode: class
property, This tells Tailwind CSS that we're changing the theme manually instead of relying on the system preference.
module.exports = {
darkMode: "class",
purge: ["./components/**/*.{js,ts,jsx,tsx}", "./pages/**/*.{js,ts,jsx,tsx}"],
theme: {},
variants: {},
plugins:[]
};
We're almost done. We need a special Nextjs page called _document.js
, This page is used to update the <html>
and <body>
tags. We will update the <body>
tag.
Notice the body className styling, We can specify the styling for the body depending on the theme.
// ./pages/_document.js
import React from "react";
import Document, { Html, Head, Main, NextScript } from "next/document";
class SpecialDocument extends Document {
render() {
return (
<Html>
<Head />
<body className="bg-white text-black dark:bg-black dark:text-white">
<Main />
<NextScript />
</body>
</Html>
);
}
}
export default SpecialDocument;
Aaaaand we're done! Go ahead and test it out, Pretty sure it's going to work :‑)
Note about useTheme hook
One problem you may encounter is that theme
returned from calling useTheme
is undefined, If that's the case for you make sure that the page is mounted on the client side!
I hope this post was helpful for you, Happy Coding!
Top comments (4)
How does the required
layout.tsx
come into play here?where did you find layout.tsx metioned in the code above?
I did not, I read that the
layout.tsx
file is required, but was unaware of the distinction between the Pages and App router. That's why i was confused...When using an App router u can just create a simple Providers component that u use to wrap the
body
element with any Context Providers. This might be a nice addition for NextJS rookies.Thanks a ton 🚗