Publish Posts After a Date in Gatsby
Tags: gatsby, react, javascript, webdev
Published: 2019-11-07 00:38:16

---
title: Publish Posts After a Date in Gatsby
published: true
description: Control when your Gatsby posts go live based on the date.
tags: gatsby, react, javascript, webdev
canonical_url: https://stevenmercatante.com/publish-posts-after-date-in-gatsby
cover_image: https://res.cloudinary.com/dovoq8jou/image/upload/v1573086522/articles/gatsby-publish-posts-after-date.png
---
___

*This post was originally published at [stevemerc.com](https://stevenmercatante.com/publish-posts-after-date-in-gatsby)*
___

I like writing articles ahead of time and only have them listed on my site based on whether the current date is greater than or equal to the article's `date` attribute. This means I get to write a bunch of content at once, but release it over time so there's a constant stream of new material on my site without having to rush to write it the night before.

_Note: This lesson builds upon my previous [Add a Published Field to Your Gatsby Posts to Control Their Visibility](https://stevemerc.com/manage-draft-posts-in-gatsby/) article._

## The Solution

First, make sure your article/post/whatever has a `date` attribute in its frontmatter. For example, here's this post's frontmatter:

```yaml
---
title: Publish Posts Based After a Date in Gatsby
date: '2019-10-08'
published: true
---

```

I'm already filtering my query to check the article's `published` attribute, so I need to add an additional check against its `date`. Let's add a filter that only returns articles whose `date` is less than or equal to the current date.

```graphql
query AllArticles($currentDate: Date!) {
  allMdx(
    filter: {
      frontmatter: { published: { eq: true }, date: { lte: $currentDate } }
    }
    sort: { fields: [frontmatter___date], order: DESC }
  ) {
    edges {
      node {
        fields {
          slug
        }
        frontmatter {
          date(formatString: "MMMM DD, YYYY")
          title
        }
      }
    }
  }
}
```

But now we've gotta pass in that `$currentDate` variable, so open up your `gatsby-node.js` file and add the following:

```javascript
// gatsby-node.js

exports.onCreatePage = ({ page, actions }) => {
  const { createPage, deletePage } = actions
  deletePage(page)
  createPage({
    ...page,
    context: {
      ...page.context,
      currentDate: getCurrentDate(),
    },
  })
}
```

[`onCreatePage`](https://www.gatsbyjs.org/docs/node-apis/#onCreatePage) is provided by Gatsby and is called whenever new pages are created. By overriding it here, we can pass additional data (`currentDate`) via its `context` object that'll be made available to all downstream components.

Here's the `getCurrentDate` implementation:

```javascript
// gatsby-node.js

/**
 * Returns the current date in YYYY-MM-DD format
 */
function getCurrentDate() {
  const d = new Date()

  let month = (d.getMonth() + 1).toString()
  if (month.length < 2) {
    month = `0${month}`
  }

  let day = d.getDate().toString()
  if (day.length < 2) {
    day = `0${day}`
  }

  return `${d.getFullYear()}-${month}-${day}`
}
```

## One More Thing...

In my [Add Previous and Next Article Buttons in Gatsby](https://stevenmercatante.com/add-prev-and-next-article-links-in-gatsby) article I show how to add "Previous Article" and "Next Article" buttons that depend on the `published` flag. For this date filtering, I needed to update this to account for the `date` constraint, so posts that are set to be released in the future don't appear in the pagination links before they're ready.

```javascript
// gatsby-node.js

const publishedPosts = posts
  .filter(post => {
    return (
      post.node.frontmatter.published === true &&
      new Date(post.node.frontmatter.date) <= new Date(getCurrentDate())
    )
  })
  .reduce((acc, post) => {
    acc[post.node.fields.slug] = post
    return acc
  }, {})
```

## Wrapping Up

With this new logic in place, I can write as much content as I want and set it to publish on a certain date. The only thing I need to do is rebuild and deploy my site (I'm looking for a way to automate this...)

👋 **Enjoyed this post?**

Join my [newsletter](https://stevemerc.com/newsletter/?r=dev) and follow me on Twitter [@mercatante](https://twitter.com/mercatante) for more content like this.