GenRater

Blogs by Rahul J Krishnan

Styling CMS Content with Tailwind CSS

#tailwindcss
#webdev

In this article, we will be looking at how we can style content from a CMS with Tailwind CSS. This is exactly the method I have used in this blog site to style CMS content.

I'm assuming the rest of the blog site project is set up and I won't be going through those setup processes as it would be completely unrelated to our title.

The Code Before TailwindCSS

So, our starting point is that we have content in rich text format coming in from a CMS, in this site I have used GraphQL queries to get the content from GraphCMS. Now take a look at the code right below to see how long and complex it was to style and display the CMS content before using the magic of Tailwind CSS.

const getContentFragment = (index, text, obj, type) => {
        let modifiedText = text;
    
        if (obj) {
          if (obj.bold) {
            modifiedText = (<b key={index}>{text}</b>);
          }
    
          if (obj.italic) {
            modifiedText = (<em key={index}>{text}</em>);
          }
    
          if (obj.underline) {
            modifiedText = (<u key={index}>{text}</u>);
          }
        }
    
        switch (type) {
          case 'heading-three':
            return <h3 key={index} className="text-xl font-semibold mb-4">{modifiedText.map((item, i) => <React.Fragment key={i}>{item}</React.Fragment>)}</h3>;
          case 'paragraph':
            return <p key={index} className="mb-8">{modifiedText.map((item, i) => <React.Fragment key={i}>{item}</React.Fragment>)}</p>;
          case 'heading-four':
            return <h4 key={index} className="text-md font-semibold mb-4">{modifiedText.map((item, i) => <React.Fragment key={i}>{item}</React.Fragment>)}</h4>;
          case 'code-block':
            return (
              <pre key={index} className="overflow-x-auto mb-8 rounded-lg p-3 bg-gray-50 dark:bg-gray-800">
                <code key={index} className="mb-8">
                  {modifiedText.map((item, i) => <React.Fragment key={i}>{item}</React.Fragment>)}
                </code>
              </pre>
            );
          case 'image':
            return (
              <img
                key={index}
                alt={obj.title}
                height={obj.height}
                width={obj.width}
                src={obj.src}
              />
            );
          default:
            return modifiedText;
        }
    };

As you can see we needed a lot of if checks and switch cases to determine what type of an item it was and then style them individually. Even then the end product was not perfect.

Displaying Content with TailwindCSS

After all that struggle I came across Tailwind CSS Typography, on using which I could just delete the whole code that I have written above and instead just use a single Tailwind CSS class. So, let's see what that magic word is.

We can start off by installing the Tailwind CSS Typography plugin.

npm install @tailwindcss/typography

Next, we need to specify that plugin in the tailwind.config.js file.

plugins: [require('@tailwindcss/typography')],

With this, we have activated the magic class prose on our application.

In the case of this site, I'm using Next.js and GraphQL query to get the content and display it. We are retrieving the post contents in HTML format with GraphQL and displaying it with the code below

<div className='max-w-none' dangerouslySetInnerHTML={{__html: post.content.html}} />

Using dangerouslySetInnerHTML is React's way of displaying HTML content from another source. With just this, all our items like heading, paragraphs, list items, and code blocks would look the same which is not what we want. Like below:

content-without-prose.png

All we got to do now is add the prose class in the div tag above. With just that single class Tailwind CSS will take care of all the styling required for our content automatically.

<div className='prose max-w-none' dangerouslySetInnerHTML={{__html: post.content.html}} />

Result:

content-with-prose.png

In the picture above you can see that the list items are automatically styled.

code-block-with-prose.png

Even the code block gets its own styling.

Now, what if we are using dark mode on our application as it is common to include a dark mode for our sites nowadays.

dark-without-prose.png

All our beautiful styling goes down the drain.

Displaying Content in Dark Mode

Luckily Tailwind CSS has got us covered, what we got to do is use prose-invert class for dark mode.

<div className='prose dark:prose-invert max-w-none' dangerouslySetInnerHTML={{__html: post.content.html}} />

Now let's check out the result:

dark-with-prose.png

Just like that, we have implemented beautiful styling for long rich text content on our application.

Rahul

Rahul

I'm a front end developer hailing from Kochi, Kerala, India.

Leave a comment

Thanks for reading.