How to schedule blog posts on a static site

Written by Codemzy on November 10th, 2021

Static sites means static content, right? But if you run a blog, you might want to schedule content to maximise your productivity and consistency. Let's look at how you can schedule your posts for the future by adding dates and updating your build process.

Having your blog on a static site has loads of benefits. There are no databases, user accounts, or servers to set up. So you have less admin, fewer security concerns, and more speed. And when you are just getting started with your blog and have low traffic, a static blog often means free hosting!

But since you are only hosting static content, how would you schedule a post?

Why would you need to schedule a blog post?

If you write a blog, at some stage, you will probably want to schedule content.

Some weeks you might be feeling super creative. Maybe you will write a few posts that week. But you know that next week you might need to focus on other things.

Or, like me, you might enjoy having a few weeks of content scheduled in advance because it takes the pressure off. It helps you write more clearly, and come up with better content ideas.

Maybe, you want to be able to take some time off but keep a consistent publishing schedule.

Or, you have written a post that is not relevant yet - but it will be at a future date.

Scheduling posts is the answer!

But how do you schedule posts on a static site?

You could write the content ahead of time and then remember to add it to your site on the day and time you want to publish it. But that seems ineffective.

Nick Scialli came up with a pretty cool way to do post scheduling. First, creating a new branch for each blog post, then adding the content and creating a pull request, but not merging it until the scheduled date. You can even automate the process by adding a date to the pull request and triggering a GitHub Action.

This workflow seems to work well and is probably the easiest route if you use a static blog builder like Hugo or Gatsby. It's the route I would take if my static provider didn’t have a build or deploy hook.

But when scheduling a lot of content, those pull requests will start to mount up. And I would always be worried if other changes to my site in the meantime might introduce conflicts.

If you use Netlify or Vercel, you can avoid creating multiple branches and pull requests with a slightly different approach.

Most static sites don't just involve uploading finished HTML pages anymore. If you are reusing templates or writing your posts in markdown, or ReactJS, or any other framework, chances are you have a build process. And you can take advantage of that build process to schedule your posts.

Full disclosure, the way I schedule posts is probably a little more work up front, but you can preview all your scheduled posts before they go live and merge them into your repository ahead of time.

Here is the basic workflow:

  1. Add the date to the file name
  2. Teach your build process about the dates
  3. Schedule your posts!

Adding dates to filenames

If you use Gatsby or Jeckyl for your static blog, you can put the date for the post in the filename. And I did this too when I built this static blog builder (which is open source if you want to look at the code).

And adding the date to the filename has a couple of other benefits. You know by just looking at your files what date they were published. And it becomes easier to find old posts you might want to update.

You can use whatever format you want. I tend to use That way, most file systems will organise the posts in date order.

By including the date in the filename, you can schedule posts, and importantly, updates too. I never actually include the date in the final URL path, because when I update a post, I don’t want the URL to change.

Let’s look at an example.

I’m writing this post on the 30th of October. But I don’t want it to go live on my blog until the 10th of November. So the filename should be

Teach your build process

Adding dates to the filenames isn't going to solve the scheduling issue by itself. Your build process needs to know about these dates and what to publish (and when).

First, in your build process, split the filename to separate the date and the path.

const [date, path, ext] = filename.split(/[_.]/);

Then you can use the date-fns npm package to check if the date of the post is before the build time.

// import the isBefore function
import isBefore from 'date-fns/isBefore';
// check the date
if (isBefore(date, new Date())) {
    // create the post

Sometimes, I want to preview all my scheduled posts ahead of time - to check the formatting is correct and make sure any new categories or images I have added are working. So I slightly tweak the above code to:

// check the date
if (isBefore(date, new Date()) || process.env.PREVIEW) {
    // create the post

Now I can have two build scripts...

  "build": "node build/build.js"
  "dev-build": "PREVIEW=true node build/build.js",

The build script will create the blog with only the posts that should be live included. The dev-build script will show me everything, including content that is scheduled for the future. It's like having a time machine.

Schedule Builds

Now your build process knows what needs to be published, and when. There's just one problem. Your build process is only going to run when you update your Git repository.

Static site services like Netlify and Vercel connect to your Git provider, and changes on Git trigger the build. And this is great for static content.

But now we have kinda added a little dynamic content to the mix.

The good news is that both Netlify and Vercel provide build hooks that you can use to trigger a build any time you like. You can use a service like Zapier or IFTTT to do this, but you don't need to use any extra external service at all.

If you are already using GitHub, you can use GitHub Actions to trigger your builds. Here's a blog post I wrote with instructions on scheduling Netlify and Vercel builds with Github Actions.

This action is a one-time thing. You won't need to create a new trigger each time you schedule a post. You'll set up your trigger to run daily, or weekly, and leave it to your date-intelligent build process to decide which new posts need publishing.

If you are using Cloudflare Pages to host your static site, you don't need a GitHub action, you can schedule the build within Cloudflare. Here's a blog post I wrote with instructions on scheduling builds with Cloudflare.

What about GastbyJS?

You might want not want to create a blog builder or use mine. Maybe you are already using a popular static site generator, like GatsbyJS. I don't blame you!

Creating a pull request and then scheduling the merge like Nick Scialli is probably the easiest way.

But if you do want to give this a bash on Gatsby, you're going to need to create a Collection route. Call it something like src/pages/blog/{BlogPost.path}.js.

This file creates all your blog post pages, so add the date checks here. If the post should not be published yet (based on the date), don't return anything.

If you set this process up on GatsbyJS, Hugo or any other static builder, and write a blog post about it, let me know - I will link to it.