Tailwind & Gatsby Integration

July 14, 2020

I decided on using Tailwind CSS because I just wanted to get straight into building the site and wasn't really keen on designing and writing CSS. After hearing good things from my a friend (thanks @mishterkurth!) I decided to give it a crack and use it as my theme/styling solution for this Gatsby build.

Integration Guide

First steps were to install Tailwind:

npm install tailwindcss --save-dev

Configure Tailwind using npx. This will create a tailwind.config.js file in the root, I left all the settings blank.

npx tailwindcss init

Next up, we need to install the Gatsby PostCSS plugin

npm install --save gatsby-plugin-postcss

I then added the plugin to the gatsby-config.js along with some config for remark:

plugins: [
	...
	`gatsby-plugin-postcss`,
    {
      resolve: `gatsby-transformer-remark`,
      options: {
        plugins: [
          {
            resolve: `gatsby-remark-prismjs`,
            options: {
              // Class prefix for <pre> tags containing syntax highlighting;
              // defaults to 'language-' (e.g. <pre class="language-js">).
              // If your site loads Prism into the browser at runtime,
              // (e.g. for use with libraries like react-live),
              // you may use this to prevent Prism from re-processing syntax.
              // This is an uncommon use-case though;
              // If you're unsure, it's best to use the default value.
              classPrefix: "language-",
              // This is used to allow setting a language for inline code
              // (i.e. single backticks) by creating a separator.
              // This separator is a string and will do no white-space
              // stripping.
              // A suggested value for English speakers is the non-ascii
              // character '›'.
              inlineCodeMarker: null,
              // This lets you set up language aliases.  For example,
              // setting this to '{ sh: "bash" }' will let you use
              // the language "sh" which will highlight using the
              // bash highlighter.
              aliases: {},
              // This toggles the display of line numbers globally alongside the code.
              // To use it, add the following line in gatsby-browser.js
              // right after importing the prism color scheme:
              //  require("prismjs/plugins/line-numbers/prism-line-numbers.css")
              // Defaults to false.
              // If you wish to only show line numbers on certain code blocks,
              // leave false and use the {numberLines: true} syntax below
              showLineNumbers: false,
              // If setting this to true, the parser won't handle and highlight inline
              // code used in markdown i.e. single backtick code like `this`.
              noInlineHighlight: false,
              // This adds a new language definition to Prism or extend an already
              // existing language definition. More details on this option can be
              // found under the header "Add new language definition or extend an
              // existing language" below.
              languageExtensions: [
                {
                  language: "superscript",
                  extend: "javascript",
                  definition: {
                    superscript_types: /(SuperType)/,
                  },
                  insertBefore: {
                    function: {
                      superscript_keywords: /(superif|superelse)/,
                    },
                  },
                },
              ],
              // Customize the prompt used in shell output
              // Values below are default
              prompt: {
                user: "root",
                host: "localhost",
                global: false,
              },
              // By default the HTML entities <>&'" are escaped.
              // Add additional HTML escapes by providing a mapping
              // of HTML entities and their escape value IE: { '}': '&#123;' }
              escapeEntities: {},
            },
          },
        ],
      },
    },
],

Now we have PostCSS and Tailwind installed, we can use some PostCSS in gatsby-browser.js to start using Tailwind:

import "./src/css/tailwind.css"
import "./src/css/markdown.css"

Note: I've used a markdown.css here to apply specific styling to the markdown block that is generated, I'm using Tailwind base styles with '@apply' to add some basic styling to the elements within the markdown blocks.

/* Markdown Styles */

/* Global */
.markdown {
  @apply leading-relaxed;
}

/* Headers */
.markdown h1,
.markdown h2 {
  @apply text-2xl my-6 font-bold text-gray-800;
}
.markdown h3,
.markdown h4,
.markdown h5,
.markdown h6 {
  @apply text-xl my-3 font-semibold;
}

/* Links */
.markdown a {
  @apply text-orange-900;
}
.markdown a:hover {
  @apply text-orange-600 underline;
}

/* Paragraph */
.markdown p {
  @apply mb-4 text-gray-800;
}

/* Lists */
.markdown ul,
.markdown ol {
  @apply mb-4 ml-8 text-gray-800;
}
.markdown li > p,
.markdown li > ul,
.markdown li > ol {
  @apply mb-0;
}
.markdown ol {
  @apply list-decimal;
}
.markdown ul {
  @apply list-disc;
}

/* Blockquotes */
.markdown blockquote {
  @apply p-0 p-2 mx-6 bg-gray-100 mb-4 border-l-4 border-gray-400 italic;
}
.markdown blockquote > p {
  @apply mb-0;
}

/* Tables */
.markdown td,
.markdown th {
  @apply px-2 py-1 border border-gray-400;
}
.markdown tr:nth-child(odd) {
  @apply bg-gray-100;
}
.markdown table {
  @apply mb-6;
}

/* Images */
.markdown img {
  width: 100%;
  @apply py-4;
}

/* Code blocks */
.gatsby-highlight {
  @apply mb-6;
}

Meanwhile, tailwind.css simply initialises the base Tailwind styles.

@tailwind base;
@tailwind components;
@tailwind utilities;

PurgeCSS Integration

To cut down on the additional styles that I'm not using, I made using of the Gatsby PurgeCSS plugin.

Install it first:

npm install gatsby-plugin-purgecss

Next, in your gatsby-config.js make sure to add it after the postcss plugin.

PurgeCSS will go through your site and basically detect what CSS you are not using and then ignore those classes as part of the build. Since your markdown styling is not part of this, you need to explicitly tell it to ignore any styling you've applied (like we've done above).

You can do this by specifying any files to ignore in the ignore array like I've done below for markdown.css and the Prism JS styles and themes.

{
      resolve: `gatsby-plugin-purgecss`,
      options: {
        printRejected: true, // Print removed selectors and processed file names
        develop: true, // Enable while using `gatsby develop`
        tailwind: true, // Enable tailwindcss support
        // whitelist: ['whitelist'], // Don't remove this selector
        ignore: [
          'node_modules/prismjs/', 
          'node_modules/prism-themes/', 
          'src/css/markdown.css', 
        ], // Ignore files/folders
        // purgeOnly : ['components/', '/main.css', 'bootstrap/'], // Purge only these files/folders
      },
    },