DEV Community

Cover image for Nextjs theme managing with next-themes and Tailwind CSS
m0nm
m0nm

Posted on

Nextjs theme managing with next-themes and Tailwind CSS

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;
Enter fullscreen mode Exit fullscreen mode

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: {}
  }
};
Enter fullscreen mode Exit fullscreen mode

-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:[]
};
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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)

Collapse
 
indymaat profile image
Indy Maat

How does the required layout.tsx come into play here?

Collapse
 
abhishek61067 profile image
abhishek61067

where did you find layout.tsx metioned in the code above?

Collapse
 
indymaat profile image
Indy Maat • Edited

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...

"The top-most layout is called the Root Layout. This required layout is shared across all pages in an application. Root layouts must contain html and body tags"

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.

Collapse
 
acidop profile image
Zeeshan

Thanks a ton 🚗