Derek FeatherstoneEverything is a work in progress

Learning Gatsby (and React and GraphQL)

Derek Featherstone / Published:

This site is built on GatsbyJS (at least for now). That means that it’s really built on React, and has a whole bunch of GraphQL built into it. I’m going to write about the things that I learn, not so much for people that are reading it, but mostly for myself so that I can remember things, and follow my own journey learning Gatsby, React, GraphQL, and whatever else I end up learning along the way. (I think that’s my way of saying, dear reader, that this post may be completely boring to you, so be prepared for that. I’m writing it anyway because it is primarily valuable to me and making sense of my learning process.)

GatsbyJS, ReactJS, and GraphQL logos

I have a bit of FOBI (Fear of Becoming Irrelevant) and that’s in part that my job has involved me advising people about code and design. I haven’t built a new thing in a while. I wanted to build something again, and here I am, learning Gatsby and React.

Learning GatsbyJS: mindset

The big picture things I’ve learned so far:

  1. If you’re newish to Gatsby, you’re not going to understand all the decisions that went into how the app is architected, but bottom line, you don’t need to in order to get started if you’re using one of the blog starters.
  2. The moment you want to customize you’re going to start digging in and trying to figure out “What is the best way to… ?” You’re asking an impossible question if that’s what you’re asking at the start of your journey. You’ll go off and research and you’ll read and you’ll tinker, but you won’t know the best way any time soon. Be happy with getting something working, but you must PROMISE yourself that you need to go back later as you learn more and revise, revisit, refactor. Making some progress is better than sitting there worrying about “What’s the best way to…?”

My biggest lesson so far

I started by using the gatsby-starter-blog and it gave me a big boost out of the gate to start creating content. But the biggest thing it gave me was the opportunity to start in the middle rather than at the beginning. That meant I wasn’t agonizing over how to start, because someone did for me.

But I wanted to customize right away. I created a few blog posts using the defaults and writing the posts in Markdown, and that went reasonably well. I created a few static pages too (my about page, my speaking page, and my contact page), simply by copying the pages and changing a bit of content and names of classes. Pretty easy.

The first challenge

I wanted to create a longer form piece of content that didn’t really fit as a blog post, but I wanted to use use Markdown (because it is quite easy to write with Markdown). My first instinct was dig through the code and figure out how blog posts work (they are Markdown that is transformed into HTML), so that I could create a Markdown file and have Gatsby convert it to HTML. I spent a while trying that. After making almost no progress I decided I needed another tactic.

Since I didn’t know what I was doing really, I solved the need another way. I hacked at the code to get it to do what I wanted: I added an isBlog field to the frontmatter of each post, and for the one I didn’t want to show up in the blog post list, I gave it a value of false.

Example frontmatter:

Here’s this blog post’s frontmatter:

    ---
    title: Learning Gatsby (and React and GraphQL)
    date: "2020-02-17 21:27:30"
    description: Learning Gatsby means learning React and GraphQL, and I'm ok with that. Here's some things I've learned so far.
    author: Derek Featherstone
    isBlog: true
    ---

Example GraphQL (note the isBlog)

    allMarkdownRemark(sort: { fields: [frontmatter___date], order: DESC }) {
        edges {
            node {
            excerpt
            fields {
                slug
            }
            frontmatter {
                date(formatString: "MMMM DD, YYYY")
                title
                description
                isBlog
            }
            }
        }
    }

I updated a few other files so that it conditionally output entries to the list if they had isBlog: true. It works! I’m happy!

Until…

The second challenge

I decided to get some RSS going. Turns out that the starter has an RSS feed by default. I expose it via a link, and I’m happy and proud that I now have RSS.

And then I see that a few people… scratch that… only one person - Chris Shiflett - told me my RSS was broken. I needed to dig in.

That larger, static thing that I didn’t want to be a post was showing up in the RSS feed and it was causing parsing errors. Yes, the errors are a thing, but bottom line, I didn’t want that “static page” showing up in the RSS feed if it wasn’t also showing up in the blog post list.

Fixing RSS meant learning more about GraphQL

I start trying to fix the RSS feed and I get to the point where I am looking for conditional logic to build the RSS feed and to only add posts to the feed if isBlog is true. And in doing that research I see that GraphQL can be filtered.

Instead of pulling back all the posts and conditionally building the feed, I should actually filter the GraphQL, so I don’t even need to build in conditional logic.

I did that, learning about filtering in GraphQL along the way. Fixed it, and now my RSS feed is squeaky clean.

Example of my new, filtered GraphQL

    allMarkdownRemark(filter: {frontmatter: {isBlog: {eq: true}}},sort: { fields: [frontmatter___date], order: DESC }) {
        edges {
            node {
            excerpt
            fields {
                slug
            }
            frontmatter {
                date(formatString: "MMMM DD, YYYY")
                title
                description
                isBlog
            }
            }
        }
        }

As you can see in the example above, I added isBlog to the data I pulled back from the GraphQL queries, but since I’m filtering, I don’t need to do that any more.

Here’s the problem

Now I’ve realized the error of my ways. I created an entire structure around this concept of adding an isBlog field to each piece I write, and I modified parts of Gatsby that I didn’t necessarily need to modify.

Because knowing what I know now, I don’t think I’d have gone down this isBlog route in the first place. I’d have gone deeper and spent more time trying to answer the questions about getting another file that isn’t in the /blog/ folder to be parsed as Markdown.

I’ve spent hours heading down a path that I didn’t even need to, if I had spent more time figuring out the way that Gatsby processes Markdown files.

Now what?

Now that I’ve learned more about how GatsbyJS all comes together to create a site, I’m going to go back and see if I can get Markdown processing to happen for files that aren’t in /blog/ — because if I can get that working, then I can go back to my whole isBlog strategy and rip that right out. I only built it that way because I was impatient in understanding Markdown processing and because I could hack something on there pretty quickly.

I likely could have spent 45-90 minutes more and had it working the way I wanted it to. Instead, I’ve spent likely more than a handful of hours working on solving the problems I created by using the isBlog strategy. Yes, I’d do it differently next time. Yes, I’d be quicker next time. Yes, I need to get better with React, and GraphQL, and Gatsby plugins, and all the things.

Yes, I spent hours doing work that I’m about to undo. HOWEVER — and I cannot emphasize this enough — all of that time is not wasted time. It’s called learning.