How to Style WordPress Blog Content with Gatsby and Tailwind CSS

How to Style WordPress Blog Content with Gatsby and Tailwind CSS

This is a short and sweet blog post about how to style WordPress content with Gatsby using a class based CSS Framework like Tailwind CSS. I'm using Tailwind CSS as an example because I'm a fan of its utility based approach, but the same method can be used with any framework that uses class names for style, such as Bootstrap or Bulma.

The Problem

When using WordPress as the headless CMS for your Gatsby site, you want to control the style of your content in Gatsby/React, not WordPress.  And you need to do this by adding class names to the content of blog posts stored in WordPress. However, when fetching post data from GraphQL you see that the content returned has WordPress' default layout.

WordPress Content Returned with Naked HTML Tags

Since the responsibility of styling is on Gatsby, we should not make any changes to how WordPress renders our content. Resulting in un-formatted content in Gatsby.

Unformatted Text in Gatsby

Solution

To fix the issue, we can use the html-react-parser's optional replace functionality. While not documented in the repo's Readme, we can alter the react component's className attribute while parsing the string format content from WordPress and inject our desired CSS class names, assuming your styling requirements are not overly complex.

Here's a quick example of how I am currently using it on my new Gatsby blog:

  import parse from "html-react-parser"

  const mapping = {
    "p": "leading-relaxed text-lg mb-6",
    "blockquote": "border-l-4 border-green-500 text-center pl-5 italic",
    "h2": "title-font text-white font-semibold mb-6 text-3xl",
    "h3": "title-font text-white font-semibold mb-6 text-2xl",
    "h4": "title-font text-white font-semibold mb-6 text-2xl",
    "h5": "title-font text-white font-semibold mb-6 text-xl",
    "a": "text-white",
    "em": "font-thin text-white text-lg leading-relaxed",
    "ul": "mb-6",
    "li": "mb-6 ml-5 text-lg"
  };

  const options = {
    replace: (node) => {
      const className = mapping[node.name]
      if (className) {
        node.attribs.className = className;
        return node
      }
    },
    trim: true
  };

// In render
<div className="container xl:w-1/2 lg:w-3/4 w-full px-5 py-16 w-full mx-auto">
	{parse(post.content, options)}
</div>

The classNames are Tailwind CSS utility classes for my present blog. And since Gatsby is compiled and served as static web pages, we do not have to worry about the performance overhead of this mapping.  The resulting blog post looks like this:

Formatted Blog Post

Hope that helps! If you have any feedback tweet at me @ItsTrueInTheory.

Show Comments