Don’t use frontmatter to seperate your markdown files in GatsbyJS - Use the file system
George Nance
Posted on August 29, 2020
Introduction
I am going to walk you through how to separate your markdown files in Gatsby in a way that more sense then a frontmatter field.
How splitting up markdown is normally done
For the longest time I had to use solutions like front matter fields to specify the difference between posts and pages types
Before I learned you could tell GraphQL to know the which markdown file was a page or post. My front matter would look something like this:
---
title: 'How to be productive as a programmer with ADHD'
date: '2020-06-19'
published: true
tags: ['adhd', 'productivity']
coverImage: cover.jpg
type: article
description: Being productive while having ADHD can sometimes feel like a colossal task.
---
I would use type: article
so I could filter out only posts or articles.
Why its bad
- Adds extra syntax to every markdown file
- It can easily become error prone
- File Systems were designed for this task.
I wanted to simplify how my blog generated articles so I could focus on creating content and not figuring out why a post was missing.
And I already had a folder structure like this:
Wouldn’t it be nice if GatsbyJS knew if a markdown file was a page or blog post based on the folder it's in?
That makes more sense to me.
Prerequisites
You need to have gatsby-source-filesystem
installed.
If you are using gatsby-transform-remark
or gatsby-plugin-mdx
you will already have this installed. 👍
Step 1 - Create the folder structure
Create the folder structure you want to use.
I like to separate my posts from my code so I put mine at the root level like thisproject-folder/content
This is the folder structure I will use
📂 content
├── 📂 blog
│ ├── 📂 hello-world
│ │ ├── 📄 index.md
│ │ └── 🖼 salty\_egg.jpg
│ ├── 📂 my-second-post
│ │ └── 📄 index.md
│ └── 📂 new-beginnings
│ └── 📄 index.md
└── 📂 pages
├── 📂 about
│ ├── 📄 index.md
│ └── 🖼 profile-pic.jpg
└── 📂 now
└── 📄 now.md
Each page or blog post has its own folder. This makes it easy to keep images or files it needs organized.
Step 2 - Set up the file system in Gatsby
Install gatsby-source-filesystem
if you don’t have it
yarn add gatsby-source-filesystem
We are going to be using the Gatsby Source File System to separate our folders.
To do this, first add gatsby-source-filesystem
as a plugin to gatsby.config.js
. You might already have this added.
For each type of content you want separated add a new gatsby source filesystem object with the name and path.
In our case, we want to separate posts and pages, so we need 2 sections.
It should look something like this:
plugins: [
{
resolve: `gatsby-source-filesystem`,
options: {
path: `${\_\_dirname}/content/blog`,
name: `blog`,
},
},
{
resolve: `gatsby-source-filesystem`,
options: {
path: `${\_\_dirname}/content/pages`,
name: `page`,
},
},
...
}
Step 3 - Update Gatsby config
In gatsby-node.js
add this code to onCreateNode
.
exports.onCreateNode = ({ node, getNode, actions }) => {
const { createNodeField } = actions;
if (node.internal.type === `MarkdownRemark`) {
const parent = getNode(node.parent);
let collection = parent.sourceInstanceName;
createNodeField({
node,
name: 'collection',
value: collection,
});
}
};
If you are using MDX, just swap out allMarkdownRemark
for Mdx
First off, we make sure that the node we are editing is a markdown file, we are grabbing the parent node so we can access some additional information.
sourceInstanceName
is the field we set on gatsby-source-filesystem
in the last step.
allMarkdownRemark
alone does not have this field for us to use so we have to get it from the parent.
Then you add a field
to the markdown node for the collection it belongs to.
Step 4 - Let the separating begin
We can now pass a filter to gatsby to let it know what collection we want to access. Hooray! No more frontmatter types
query {
allMdx(
sort: { fields: [frontmatter\_\_\_date], order: DESC }
filter: { fields: { collection: { eq: "posts" } } }
) {
edges {
node {
id
fields {
slug
}
frontmatter {
title
published
slug
date(formatString: "MMMM DD, YYYY")
}
excerpt(pruneLength: 280)
}
}
}
}
Wrap Up
Thanks for stopping by! This was a quick tutorial I made to solve an issue I was having with GatsbyJS. This article is a part of my "write one blog post a month" challenge.
If you would like to see more tutorials like this, let me know on twitter or by subscribing to my newletter.
Also I recommmend checking out Josh W Comeau if you want more Gatsby goodness. His tutorial on darkmode inspired me to add it to my site
Posted on August 29, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
August 29, 2020