Search code examples
next.jsclass-names

How do I use the npm classnames library in next.js to optionally apply styles from a css file?


In the html below, I am optionally applying the bootstrap classes, alert-danger or alert-primary depending on message.error or message.info. The target classes are bootstrap classes and it works as expected.

<div
   className={classnames(`alert, ${styles.alertDiv}`, {
   "alert-danger": message.error,
   "alert-primary": message.info,
   })}
  >

Now, in place of alert-danger, I want to apply a style from a css file, $(styles.activeDiv) if message.error is true. In other words I want to replace alert-danger with $(styles.activeDiv). How do I do this.


Solution

  • In Next.js and in Bootstrap you are able to override the default CSS styling or write specific component level styling Next.js Built-in CSS Support. There are many ways to accomplish this, you could pass in a style object as an inline style attribute. I think a simple way to do it is just to useState hooks. This one toggles between two different CSS classes but you can alter to suit your needs:

    In this example, the className changes when you click the div

    codesandbox example of Dynamic ClassName

        import { useState } from "react";
        
        export default function IndexPage() {
          const [dynamicClassName, setDynamicClassName] = useState("info");
          
          const handleClassChange = () => {
            console.log("changing div class name");
            dynamicClassName === "info"
              ? setDynamicClassName("alert")
              : setDynamicClassName("info");
          };
        
          return (
            <>
              <div className={dynamicClassName} onClick={handleClassChange}>
                This div has a dynamic CSS class based on click
              </div>
        
              <style jsx>
                {`
                  .alert {
                    color: red;
                    border: 5px solid red;
                  }
        
                  .info {
                    color: green;
                    border: 5px solid green;
                  }
                `}
              </style>
            </>
          );
        }
    

    note: edited for a more specific working example