Micah Godbolt

3 Things I Learned Creating My Gatsby Blog

I've had my new blog up and running for a bit now, but have been having trouble pulling the trigger on writing something new. Seemed every topic that came to mind deserved several hours of work to properly craft. Sure, those blogs have their time and place, but I really just need to start writing.....something! So I did what anyone else would do: I asked twitter.

One of the first responses I got was the following:

It might sound a bit clickbaity, but Ken was onto something! See, I'd had in mind to blog my entire Gatsby site building experience, but as you might expect, that'd be a big project! I also kept pushing off starting an article like that because I don't quite feel 'done' setting this thing up. But that's the problem...I'd never be done! So Ken's suggestion is just what I needed: Write about something important, but limit it to a few bite size chunks.

So...Here goes!

Problem 1: To start from scratch vs start with a template

Out of the box, Gatsy makes it really easy to build a basic site, but once you step into blogging it gets a bit more complex. Markdown vs MDX, digging into GraphQL, templates, gatsby-node.js, createPage, onCreateNode. If your first Gatsby site is a blog, you are going to be diving head long into some complex topics.

Solution 1: Starter project

Starting off with a starter project offers a ton of value. Take the Gatsby Starter Blog for example. This project will get you off the ground running in a heartbeat. It gives you a working blog with good SEO, out of the box styling, RSS feed, and a solid opinionated setup.

On the other hand, it uses Markdown instead of MDX, is missing TypeScript support, and uses some opinionated styling pulled in from the Wordpress 2016 template. Weird.

So yeah, you get a ton out of the box, but then you'll find yourself ripping things out, adding things in, and constantly wondering if it would have been easier to start from scratch.

Solution 2: Start from scratch

Gatsby documentation is pretty amazing. The more I use the product, the more I look forward to digging into to their docs to find solutions. This was also the case when starting from scratch.

  1. The quick start got me up and running....quickly.
  2. Programmatically creating pages was pretty straight forward following their instructions
  3. Working in GraphQL is well spelled out in the docs, and GraphiQl is a game changer!
  4. If I was having trouble with a concept, or wonder what I was missing, I could always take a look at the Gatsby Starter Blog (and I often did)

In the end, I decided to go with "Start from scratch" and I'm quite thankful for it. I learned a ton about Gatsby and GraphQL in the process, and have a better understanding of the entire lifecycle and flow of the framework.

Problem 2: MD vs MDX

If you came to this Gatsby party because you loved React, then I don't think there is ANY reason that you shouldn't be checking out MDX. With MDX you can mix Markdown and React into the same file like this:

import { myComponent } from '../components/myComponent';
# Markdown Here
And Here.
<p> You can still do HTML in markdown </p>
<myComponent myProps='rock'>
But you can also import and render JSX in the same file!
</myComponent>

MDX is the perfect React documentation format! No more writing MD files the combining them with code snippets in a JSX file. You don't even need to import React in MDX.

The Real Problem

As great as MDX is, there's something equally as great called NetlifyCMS. Yes, it's made by Netlify, but no, it has absolutely nothing to do with Netlify's product. It's a React application you can quickly install into Gatsby (or any other static site generator) that simplifies the authoring process of new and edited Markdown files. I'm actually using it right now!

The secret sauce of NetlifyCMS is that it gives users a traditional website.com/admin URL they can access that lists all of their content and lets them create, edit, upload images, and publish without ever touching a terminal or code editor. Under the hood, NetlifyCMS treats GitHub as your database. It uses GitHub for authentication, and once you're done, saving simply creates a PR that adds a markdown file (and any uploaded images) to your GitHub repo. Check out Issue 17 here.

This doesn't sound like a problem yet does it? No, the problem is that NetlifyCMS doesn't support MDX out of the box. When you search for NetlifyCMS and MDX you come across this long standing feature request in their issue queue.

I thought I was sunk! I went as far as setting up my blog entries as Markdown, then using MDX for my site pages. While this approach worked, it felt dirty, and it made templating really confusing because sometimes the data was Markdown (yeah for dangerouslySetInnerHTML!) and sometimes it was MDX (OMG MDXProvider is amazing).

Fortunately, after reaching out to the NetlifyCMS team, I was informed that I COULD use their tool to edit MDX files, though I wouldn't get any of the React components to render in the preview(which I could live with). Best part was that it took all of 2 lines of code to fix:

// config.yml
// inside my blog collection
extension: "mdx";
format: "frontmatter";

Problem 3: Differentiating between blog posts and site pages

Now that all of my pages were in MDX, I had a new problem. When I made a query for allMdx, I'd get blog pages as well as my other static pages (Home, About Me etc). When you import files into Gatsby using gatsby-source-filesystem you get to name the collection, but this turned out to not be enough:

// gatsby-config.js
{
resolve: `gatsby-source-filesystem`,
options: {
path: `${__dirname}/blog`,
name: 'blog'
}
}

When you grab files with the allMdx query, you don't actually have direct access to that name string because it is on the parent of the MDX file. So I found myself constantly doing this anytime I dealt with allMdx:

exports.onCreateNode = ({ node, actions, getNode }) => {
const parent = getNode(node.parent);
if (parent.sourceInstanceName === "blog") {
// do stuff
}
};

To clean this up and ensure that I could always filter out non blog content I use createNodeField to set the name value directly on the Mdx node.

exports.onCreateNode = ({ node, actions, getNode }) => {
// ...
createNodeField({
name: `name`,
node,
value: parent.sourceInstanceName
});
};

Now I could filter out non blog content directly in my GraphQL query

allMdx( filter: { fields: { name: { eq: "blog" } } } )

Conclusion

I've built blogs with Wordpress, Drupal, Jekyll, Metalsmith and Gatsby, and I can say with certainly that this has been one of the best experiences I've had building a new site. The technological combination of React, GraphQL and NetlifyCMS is hard to beat, and the documentation and community around Gatsby is second to none. I feel like I'm part of a larger movement here, moving the web forward...one blog at a time.

What have you learned using Gatsby? What hurdles did you need to overcome? Was it worth it? It sure was for me.

Thanks Ken....next suggestion!