Creating Multiple Themes in Tailwind CSS and Next.js
Tags: webdev, nextjs, css
Published: 2023-08-17 06:08:17

Tailwind [CSS](https://en.wikipedia.org/wiki/CSS) has gained immense popularity for its utility-first approach to styling, enabling developers to quickly build modern and responsive user interfaces. When combined with a powerful framework like [Next.js](https://ultroneous.com/hire-nextjs-developer), you have a winning combination for building dynamic and performant web applications. In this tutorial, we'll explore how to create multiple themes using Tailwind CSS and integrate them seamlessly into a Next.js project.

**Step 1: Setting Up Your Next.js Project:**

To begin, open your terminal and enter the following command to create a new Next.js project using the latest version:

```tsx
npx create-next-app@latest
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6xv2lkznhvnbyac8vpy5.png)
Once the project generation is complete, navigate into the newly created project directory by running:

```tsx
cd my-app
```

**Step 2: Creating Multiple Theme Variants:**

In your project's source directory, navigate to the styles folder and open the global.css file and set up your base Tailwind CSS configuration:

```tsx
@tailwind base;
@tailwind components;
@tailwind utilities;

/* Your base theme settings */
@layer base {
  html {
  --color-primary: #4285f4;
  --color-secondary: #34a853;
  --color-buttons: #fbbc05;
  --color-typography: #ea4335;
  }
}
```
Create a folder named themes inside the styles directory.

Inside the themes folder, create individual CSS files for each theme variant: theme1.css, theme2.css, and theme3.css

Customise each theme variant's color palette, typography, and other design attributes within their respective CSS files.

src/styles/themes/theme1.css

```tsx
html[data-theme="theme1"] {
--color-primary: #f98866;
--color-secondary: #80bd9e;
--color-buttons: #89da59;
--color-typography: #ff320e;
}


src/styles/themes/theme2.css
html[data-theme="theme2"] {
--color-primary: #f4cc70;
--color-secondary: #6ab187;
--color-buttons: #de7a22;
--color-typography: #20948b;
}
```
src/styles/themes/theme3.css

```tsx
html[data-theme="theme3"] {
--color-primary: #f1f1f2;
--color-secondary: #a1d6e2;
--color-buttons: #bcbabe;
--color-typography: #1995ad;
}
```
In global.css Below your base theme settings, you can start importing your theme variants.

```tsx
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer base {
html {
--color-primary: #4285f4;
--color-secondary: #34a853;
--color-buttons: #fbbc05;
--color-typography: #ea4335;
}
@import "themes/theme1.css";
@import "themes/theme2.css";
@import "themes/theme3.css";
}
```
**Step 3 : setting up tailwind Configuration**

Open the tailwind.config.js file and configure it to extend the theme colors using the CSS custom properties defined in your global.css

Tailwind.config.ts

```tsx
module.exports = {
    content: [
      './src/pages/**/*.{js,ts,jsx,tsx,mdx}',
      './src/components/**/*.{js,ts,jsx,tsx,mdx}',
      './src/app/**/*.{js,ts,jsx,tsx,mdx}',
    ],
    theme: {
      extend: {
        colors: {
          primary: 'var(--color-primary)',
          secondary: 'var(--color-secondary)',
          buttons: 'var(--color-buttons)',
          typography: 'var(--color-typography)',
        },
      },
    },
    plugins: [],
  };
```
This configuration tells Tailwind CSS to use the CSS custom properties (variables) defined in your global.css for the extended theme colors.

By adding this tailwind.config.js file, you're ensuring that your Tailwind styles align with the custom theme colors you've defined. This setup will help you maintain consistency throughout your application while easily switching between different themes.

**Step 4: Dynamic Theme Switching**

Inside your project directory, create a folder named utils if it doesn't exist, and then create a file named helper.ts within it.

In the helper.ts file, define a function called changeTheme that takes a theme string as an argument and applies it as a data attribute to the HTML element:

src/utils/helper.ts

```tsx
export const changeTheme = (theme: string) => {
  document.querySelector("html")?.setAttribute("data-theme", theme);
};
```
In your src/pages/index.tsx file (or another appropriate component), import the changeTheme function.

Inside your component, create buttons that, when clicked, call the changeTheme function with the corresponding theme name:

src/pages/index.tsx

```tsx
import { changeTheme } from "@/utils/helper";

export default function Home() {
  return (
   <div className='h-screen grid place-items-center bg-primary'>
    <div>
      <button className='py-2 px-8 bg-buttons text-typography m-2' onClick={() => changeTheme("")}>Default</button>
      <button className='py-2 px-8 bg-buttons text-typography m-2' onClick={() => changeTheme("theme1")}>theme 1</button>
      <button className='py-2 px-8 bg-buttons text-typography m-2' onClick={() => changeTheme("theme2")}>theme 2</button>
      <button className='py-2 px-8 bg-buttons text-typography m-2' onClick={() => changeTheme("theme3")}>theme 3</button>
    </div>
   </div>
  )
}
```
By implementing this code, you're creating a dynamic theme switching mechanism that allows users to switch between different themes by clicking the corresponding buttons. The changeTheme function sets the data-theme attribute on the HTML element, which is then used by your custom theme variants in the global.css and tailwind.config.js files to apply the correct styling.


**Conclusion:**

In this tutorial, you've learned how to create and switch between multiple themes in your [Tailwind CSS](https://tailwindcss.com/) and Next.js projects. Starting from setting up your Next.js app using the latest version, you customize themes using CSS variables in global.css. By extending the Tailwind theme in the configuration file, you ensured consistency.

The implementation of dynamic theme switching was achieved through the changeTheme function in helper.ts. Integrating theme-switching buttons in your components, as shown in the example index.tsx, allows users to instantly transform the app's appearance.

Mastering this skill equips you to cater to diverse user preferences, enhancing the user experience and showcasing your app's adaptability. With the ability to offer various themes at the click of a button, you're ready to create engaging and user-centric web applications.

Congratulations on mastering the art of multiple themes with Tailwind CSS and Next.js. Enjoy creating captivating user interfaces and delivering exceptional experiences!