DEV Community

Cover image for Using Tailwind presets for multiple tenants in Next.js
Chris Low
Chris Low

Posted on • Originally published at itschrislow.com

Using Tailwind presets for multiple tenants in Next.js

When I was tasked to build a multi-tenant SaaS application using Next.js + Tailwind on a monorepo, the internet disappointed me. There was nothing solid out there on how to load a specific Tailwind preset for a specific tenant. This was the solution I came up with, hope this helps ;)

Full repository available here.

Final result for default, Reddit and Discord themed tenants using the exact same codebase with different environment variables!

Final result

Let's dive into it!

We will be starting with the official Next.js with Tailwind example repo. To clone the example, run the following command:

yarn create next-app --example with-tailwindcss with-tailwindcss-app`
Enter fullscreen mode Exit fullscreen mode

Setup environment

Create a .env file and define a NEXT_PUBLIC_TENANT environment variable.

NEXT_PUBLIC_TENANT=reddit
Enter fullscreen mode Exit fullscreen mode

Setup Tailwind Presets

Add a tailwind folder to the root of your project with the following structure.

.
└── tailwind
    ├── default
    │   └── preset.js
    ├── reddit
    │   └── preset.js
    └── discord
        └── preset.js
Enter fullscreen mode Exit fullscreen mode

Presets take the exact same shape as the configuration in a tailwind.config.js file. Since presets are merged on top of the default, we only need to include the theme object.

// default preset.js
module.exports = {
  theme: {
    extend: {
      colors: {
        primary: "#2563EB",
      },
    },
  },
};
Enter fullscreen mode Exit fullscreen mode

Add a getPreset() helper function in the tailwind.config.js file

// tailwind.config.js
const getPreset = () => {
  if (!process.env.NEXT_PUBLIC_TENANT) 
    return [require(`./tailwind/default/preset.js`)];

  try {
    return [
      require(`./tailwind/${process.env.NEXT_PUBLIC_TENANT}/preset.js`),
    ];
  } catch (err) {
    return [require(`./tailwind/default/preset.js`)];
  }
};

module.exports = {
  presets: getPreset(),
  content: [
    "./pages/**/*.{js,ts,jsx,tsx}",
    "./components/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
};
Enter fullscreen mode Exit fullscreen mode

You're almost there

Find and replace all text-blue-600 from index.tsx with text-primary

Yay

That's it! Restart the server when you change the value of NEXT_PUBLIC_TENANT to see the changes.

Note: The values of NEXT_PUBLIC_TENANT correspond to the folder names in ./tailwind

Top comments (0)