GatsbyJS: Automatically Include Date In Blog Post Slug

There will be times where you will want to customise the slug based on fields from your markdown file. In my case, I wanted all my blog post URL's in the following format: /Blog/yyyy/MM/dd/Blog-Post-Title. There are two ways of doing this:
  1. Enter the full slug using a “slug” field within your markdown file.
  2. Use the onCreateNode() function found in the gatsby-node.js file to dynamically generate the slug.

My preference would be option 2 as it gives us the flexibility to modify the slug structure in one place when required. If for some reason we had to update our slug structure at a later date, it would be very time consuming (depending on how many markdown files you have) to update the slug field within each markdown file if we went ahead with option 1.

This post is suited for those who are storing their content using markdown files. I don’t think you will get much benefit if your Gatsby site is linked to a headless CMS, as the slugs are automatically generated within the platform.

The onCreateNode() Function

This function is called whenever a node is created or updated, which makes it the most ideal place to add the functionality we want to perform. It is found in the gatsby-node.js file

What we need to do is retrieve the fields we would like to form part of our slug by accessing the nodes frontmatter. In our case, all we require is two fields:

  1. Post Date
  2. Slug
exports.onCreateNode = ({ node, actions, getNode }) => {
    const { createNodeField } = actions
  
    if (node.internal.type === `MarkdownRemark`) {
      const relativeFilePath = createFilePath({ node, getNode, trailingSlash: false });
      const postDate = moment(node.frontmatter.date); // Use moment.js to easily change date format.
      const url = `/Blog/${postDate.format("YYYY/MM/DD")}${node.frontmatter.slug}`;

      createNodeField({
        name: `slug`,
        node,
        value: url,
      });
    }
  }

After making this change, you will need to re-run the gatsby develop command.