Adding a Draft Feature to Gatsby
Created: Sep 08, 2019 – Last Updated: Apr 26, 2021
Tags: GatsbyDigital Garden
There are a lot of guides on the internet on how to add default values to your Gatsby schema, e.g. a draft entry in the frontmatter to hide posts that are still work-in-progress. However, all these solutions are kinda hacky, as they for example require you to use environment variables or even define the draft entry in every single frontmatter you have. Since Gatsby implemented its schema customization API (opens in a new tab) there is an easy solution (and not hacky at all!) available. Most importantly: This quick tip is applicable to all data sources you have, not only markdown (and its frontmatter).
You can have a look at the codesandbox gatsby-draft-default-values (opens in a new tab) to see the working code in a minimal example.
If you want to follow the example along, you can install the default blog starter by running
gatsby new my-blog https://github.com/gatsbyjs/gatsby-starter-blog with
The default blog starter uses markdown for its content and you can use the so called frontmatter in markdown files to define additional data, such as e.g. a draft status (true or false). The goal is to define a default value for this draft status so that you don’t have to define it in every markdown file but only in the ones you’d like to be a draft.
Add this to the existing
createTypes function you have to define a nested type on the
MarkdownRemark type (read Nested types (opens in a new tab) for more info) to be able to type the draft field. On the draft field itself the custom extension is used as a directive. The directive allows you to reuse this action on other fields, too. In case you’re using a CMS or other data source than markdown you’ll need to find and define your type (instead of
MarkdownRemark) to have this working. I’d recommend using GraphiQL (
localhost:8000/___graphql) if you’re unsure about the names!
To be able to use the @defaultFalse directive, you need to define a custom extension with
source contains all fields from the frontmatter (in this case: title, description, date, and draft).
info.fieldName is the name of the field you’re applying the directive to – in this case
draft. Fields that are not provided are null by default but because draft should be a boolean you need to return
false in this case. If it’s provided simply return the value.
Read the complete guide on Creating type definitions (opens in a new tab) to get in-depth knowledge of how and why it works this way.
Now that the draft field is set up and defaults to false, you can go ahead and add a
draft: true to the frontmatter of a blogpost.
When opening GraphiQL you also should be able to query the draft field now and filter by it. A query to list all markdown posts that are not a draft looks like: