Gatsby and Classnames library: Apply CSS class depending on content of div

773 views Asked by At

I have a Gatsby project with a blog. I have a tag cloud section that shows the tags for blog posts. I also have a button/header on the actual blog post card that I want to style the same as it's corresponding tag in the tag cloud i.e. if there's a red tag for "Press Releases" in the tag cloud I want to style all blog post cards that are about Press Releases to have a red button, if there's a blue tag for "Getting Started" in the tag cloud then I want to style all blog post cards with the tag of Getting Started to be blue, and so on.

I have a PostCard component where blog post cards are styled. I am using the Classnames library to apply CSS styles depending on the value of the tag, like this:

{post.tags && <div className={
                        classNames(styles.postCardTags, {
                            [tagStyles.hiddenTag]: primary_tag === `Data schema primary`,
                            [tagStyles.tagRed]: primary_tag === `Press Release`, 
                        })
                    }> 
                    <Tags post={post} visibility="public" autolink={false} />
                </div>}
    

The above code sets the default styles for tags to postCardTags (which I have set to blue), and it sets tags with a value of "Press Release" to red.

When I run this locally on localhost:8000/ it correctly applies the styles, "Press Release" tags are correctly set to red. When I push to production, tags with a value of "Press Release" are not properly setting their CSS class to tagStyles.red and are blue. For some reason tagStyles.red is set for "Press Release" tags when the project is ran locally but when pushed to production "Press Release" tags are set to blue (i.e. styles.postCardTags).

Why are my "Press Release" tags applying the style tagStyles.tagRed when on localhost but applying the class styles.postCardTags when pushed to the live site? Is this an issue with how Gatsby builds the component?

1

There are 1 answers

0
Ferran Buireu On

I don't think you need an external package (that will be bundled increasing the project's size) to achieve this behavior. Removing the package may fix your problem since it may have SSR (Server-Side Rendering) issues. I use to change the class name depending on some parameters (like yours with tags) or props. Try:

let classNames= post.tags === 'Press Releases' ? 'red' : 'blue' // change it to styling modules

{post.tags && <div className={`defaultClass ${classNames}`}> 
                    <Tags post={post} visibility="public" autolink={false} />
                </div>
}

Note: you can add your logic inside the className template literal but it's cleaner to use an external variable.

I don't know how's your use-case, you can change the post.tags === 'Press Releases' for a includes function if needed.

As I said, you can change this behaviour to add CSS modules there.