dark mode

Implementing draft status for your blog posts in GatsbyJS

Implementing draft status for your blog posts in GatsbyJS

Will be great if Gatsby blog starter has the same status management for blog posts as WordPress. Until now I stash my blog post progress and commit my design changes. This is redundant and having draft or published statuses will make life much easier.

I prefer this status management to be simple and without needless plugins, but you can build on and make it much complex.

The tutorial will teach you how to include the draft status in your blog posts and show drafts only in development gatsby develop and hide them in production gatsby build.

To display and hide drafts, we need to know the correct environment. You can accomplish this natively by GatsbyJS with the variable process.env.NODE_ENV which returns by default two states: development and production.

But first lets go back at the beginning, we need to create a blog post. Here is an example:

---
path: '/blog/my-first-post'
date: '2019-01-07'
title: 'My first blog post'
draft: true
---

My first blog post

Notice the key-value pair draft: true the objective is to hide the post on production when the draft is true.

Second, we need to make GraphQL query from which we create HTML pages. If we have one query, there won't be any difference between environments. That is why we introduce two queries. One will be for production and the second for development. Here is an example:

export const query = graphql`
  query {
    production: allMarkdownRemark(filter: { frontmatter: { draft: { eq: false } } }) {
      edges {
        node {
          id
          frontmatter {
            title
          }
          fields {
            slug
          }
        }
      }
    }
    development: allMarkdownRemark {
      edges {
        node {
          id
          frontmatter {
            title
          }
          fields {
            slug
          }
        }
      }
    }
  }
`;

What is happening here? We query all markdowns to get their title and URL (slug) and secondly we filter them by draft: false in production.

The last step is to have a logic which will choose one of the two queries. I've created a file draft-posts.js with the following function:

module.exports = draftPosts;

function draftPosts(query) {
  const environment = process.env.NODE_ENV;

  return query[environment].edges;
}

This one can be imported and used like this:

import draftPosts from '../utils/draft-posts';
...
const Index = ({ data }) => {
    const posts = draftPosts(data);
...

If you want to use it in gatsby-node.js you need to use require:

const draftPosts = require('./src/utils/draft-posts');

Having two GraphQL queries is the way to separate your environments everything else is up to you how will implement the logic.

Related articles

© 2021 All rights reserved.