Search code examples
cssreactjsnext.jstailwind-cssserver-side-rendering

How to dynamically add classes to NextJS component using class names from CMS?


I am looking for a solution that will allow some styling options in a CMS that can dynamically change the classes of specific components in my NextJS app. My code looks like this:

pages/index.js:

...
import client from "../lib/client";

const Home = ({ headerConfig }) => {
  return (
    <>
      <Header headerConfig={headerConfig} />
      ...
    </>
  );
};

export const getServerSideProps = async () => {
  const headerConfig = await client.getDocument("headerConfig");

  return {
    props: { headerConfig },
  };
};
export default Home;

components/Header.jsx:

const Header = ({ headerConfig }) => {
  return (
    <nav className={`relative ... ${headerConfig.bgColour}`}>
      ...
    </nav>
  );
}

export default Header

However, the styling does not apply and the background colour remains unchanged although the class does seem to be injected into the class attribute on the browser.

enter image description here

I know my current method is incorrect but I am clueless as to how to fix this. Could someone help point me in the right direction?


Solution

  • I assume that you are using tailwind. If so, you cannot inject classnames into an html element. This is because tailwind only includes classes that are explicitly declared somewhere within your code (it will find classes within any string in your project depending on the configuration). You can get around this problem by adding classes to the safelist array in your tailwind.config.js file. You can also safelist classes with regex to allow all variants of certain utilities.

    However, safelisting only works if there are a specific set of classes that could potentially be injected. One option, which will be guaranteed to work but NOT RECOMMENDED, is to add a <link> in your html to the tailwind cdn. However this will include every single tailwind class in your css bundle, making it MUCH larger and your website slower.

    Another solution is to use inline styles which are calculated with javascript depending on the classes you need to inject. If you are dealing with only simple parts of tailwind (like padding, margin, or other sizing units), this may be a good approach. For example a class like p-4 would get converted to padding: 1rem in your inline styles.

    Depending on the needs of your application, one of these three approaches is probably the way to go. Hope this helps!