July 04, 2019

Getting started with the Gatsby blog starter kit

Creating a new website with the starter kit

As I mentioned in the previous blog post, I am migrating my website over to Gatsby. Initially, I considered starting from a blank slate and build everything up from scratch, but I dropped that idea and decided to speed things up, by using the Gatsby blog starter kit.

Once I have installed the Gatsby CLI, I created a new website with the blog starter.

gatsby new website https://github.com/gatsbyjs/gatsby-starter-blog

After creating the new Gatsby website, the first thing I did was to run it in development mode to see what it looks like. Unfortunately, I was off to a bad start:

Error when running Gatsby the first time

Googling the error ”Encountered duplicate defintitions for one or more documents: each document must have a unique name”, I came across this issue on GitHub. It appears as though there is some discrepancy in the way directory names are handled, and in some parts, it is handled as-is, and in other parts, it is converted to lower case. This, in turn, results in some case-sensitivity issues which causes the error. You can notice in the screenshot above the discrepancies in the directory names.

My first reaction was to update all the NPM packages to the latest version, but that did not resolve the problem. So, I took the easy way out and renamed my directories to all be lower case. That worked around the issue and I could run the starter kit.

Running the blog starter kit

Understanding where content comes from

The next thing was to understand where those blog posts come from. The starter kit is configured in such a manner that it picks up the blog posts from the content folder. You can see that the content folder contains a blog folder, which in turns contain folders for each of the blog posts. Each blog post folder contains an index.md file with the markdown (and frontmatter) for the blog post, along with any images.

The blog content folder

In the gatsby.config folder, the gatsby-source-filesystem plugin is configured to pick up the content from the blog folder.

plugins: [
    resolve: `gatsby-source-filesystem`,
    options: {
      path: `${__dirname}/content/blog`,
      name: `blog`,

The blog starter kit also has the gatsby-transformer-remark plugin configure which will convert any markdown file (.md or .markdown) into HTML content and expose those blog posts in the allMarkdownRemark field, as you can see in the simple GraphQL query below which lists the blog posts with their title and slug.

Running a GraphQL query to list the blog posts

The blog starter kit has a BlogPostTemplate defined in blog-post.js which will render all of the blog posts.

At this point, I would suggest also reading through the following official Gatsby docs:

Testing my existing content

I spent an hour or so working through the source code and docs trying to get a better understanding of how things fit together. So, I thought it was time to see what happens when I bring some of my existing content into the mix.

In my existing Hugo-based website, I put all the blog posts under the /content/blog folder - which is strangely enough the same layout the blog starter kit uses.

Hugo website blog folder structure

I decided to try it out with my three latest blog posts by copying them from the Hugo website to the Gatsby one.

Copying the three most recent blog posts to Gatsby

Switching back to the browser and refreshing my Gatsby website, you can see those three blog posts listed.

Three most recent blog posts listed

Issues with existing content

At this point, I am happy about making progress, but there are several issues.

  1. The blog starter kit puts each blog post in its own folder. My existing Hugo structure has all blog posts as individual files under the same folder. I like the Gatsby layout more for reasons I’ll discuss next time.
  2. All blog posts are on the path /blog-post-slug. My existing website has all blog posts are on the path /blog/blog-post-slug. I want to keep the blog posts under /blog/* both for organizational purposes but also to ensure I don’t have broken links when I migrate across.
  3. My blog posts don’t have dates. There is no frontmatter for the date as it is derived from the filename. You can see in the screenshots above that in Hugo all the filenames for the blog posts start with the date (in yyyy-mm-dd format).
  4. Also, because of the above, the actual slug for the blog posts I copied from Hugo contains the date in the slug for the blog posts (e.g. /2019-06-26-use-conveyor-access-iis-app-over-internet). I do not want this.

In the next blog post, I will start work on sorting out these issues.