Draft posts in Gatsby

A build time draft state solution for markdown in gatsby.

2019-05-23

Metadata
Draft posts in Gatsby
A build time draft state solution for markdown in gatsby.
2019-05-23
./gatsby-icon.png
this-site
reactjavascriptfrontendgatsby

The problem

After completing the rewrite of my personal website using gatsby, I started migrating all my content from my old website to this one. In the process, I remembered that Jekyll had a way of indicating that a post was a draft, and thus should not be included in the final built version of the website, but would still show up while developing locally. I went searching for a similar way to do this in Gatsby, but the solutions I found weren't quite what I was looking for. They all depended on adding a flag to the front matter of a post and then filtering based on that flag in your GraphQL queries. I didn't want to have to repeat this filter in every GraphQL query I performed. I preferred a solution where the draft posts just wouldn't even be included in a production build.

The Solution

My solution landed on editing the gatsby-source-filesystem plugin. According to the docs, you can pass an array of globs to ignore in the configuration for the plugin.

Using this field, I ended up with a solution that relied on a file naming convention. If a post was a draft, I would prefix the index.md file with an underscore (_index.md), then filter out any markdown files that start with an underscore in the filesystem plugin.

const isProd = process.env.NODE_ENV === 'production'

...

{
  resolve: `gatsby-source-filesystem`,
  options: {
    path: `${__dirname}/content/blog`,
    name: `blog`,
    ignore: isProd ? ['**/_*.md'] : []
  },
}

I only want this filtering to take place if the build is being run in production, thus the isProd flag. This way I don't have to filter out draft posts in all my GraphQL queries and they just get filtered out at build time.