Draft posts in Gatsby
A build time draft state solution for markdown in gatsby.
2019-05-23
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.