Oct 11, 2020

This Filesystem API made my life easier.

Building with static site generators is aimed at cutting off all the "difficult" parts and getting you started with serving content while using the same best practices and methods available.

We have a lot of them (Gatsby, Hugo, Jykll), some more straightforward than others, each solving a particular use case, and to be frank, I would rather not compare them based on usage but on the Use case. At the end of the day, it all boils down to what you are trying to do.

You see, the thing about abstraction is we have to know where to stop, as sometimes the solution might create a new problem. A problem that you have to solve.

Here's my experience with a particular problem.

Programmatically creating pages in Gatsby.

Now I love Gatsby, it makes a lot of things easier and in the process, it did open the door to a lot of other exciting things for me like GraphQL, and an API file called Gatsby-node, where a lot of my early pains came from.

The way Gatsby handles programmatically creating pages(which is a fancy way of saying, creating pages on demand by sourcing from a Content Management System) is in the following steps:

  1. Source page via Slug in Gatsby-node.
  2. Use the createPages API to create a page for each slug.
  3. Resolve that in a template component path.
  4. Create that Path and then source for all the other information using the slug as a unique identifier.

Looks something like this,

Sourcing using createPages API

Alt Text

Resolving in the Template directory

Alt Text

Sounds like a lot yes? Hence, the cover image of this blog post.

What is going on

There are a lot of reasons why Gatsby uses GraphQL, the most common is to facilitate sourcing data from different places and getting the exact thing you need.

While this is a logical reason, this process isn’t as intuitive and sometimes might not be as straightforward as my steps make it seem.

What if there was a way to make this more interesting, with fewer lines of code?

Alt Text

Gatsby file system routes API

There is always a soul of good in things "evil" if people distill it out - Shakespeare

This was an answer to my WTF questions, an API built on top of the createPages API to replaces the above steps with a more intuitive approach. This is how it works:

  1. use curly braces ({ }) in naming the file to signify dynamic URL segments that relate to a field within the node.
  2. write your query as you would for a particular page.

You can leverage this feature by running

GATSBY_EXPERIMENTAL_ROUTING_APIS=1 gatsby develop

That's the END of this blog post.... (Joking)

Ok seriously, Here's an example, If you would query a file like so :

allProduct {
  nodes {
    id # Gatsby always queries for id
    name
  }
}

Then the file name in your pages directory would be src/pages/products/{Product.name}.js

Notice the pattern? Gatsby turns anything put into the pages folder to a route, so doing this automatically makes /products/{Product.name}.js to a route.

Here's what it turns the code block into:

Alt Text

Notice how the file name is in curly braces, that's about it.

Note: This File system Routes API is built on top of the createPages API so you will not have to refactor your existing applications 😉

In addition to the simplification, Gatsby automatically includes a gatsbyPath field on every model used by collection pages.

The gatsbyPath field must take an argument of the filePath it is trying to resolve. This is necessary because it’s possible that one model is used in multiple collection pages.

This is an example of what the gatsbyPath looks like in a query:

Alt Text

This feature is still experimental and as it gets built out I am sure it will create a more interesting way to query pages in Gatsby.

Wait there is more...

This file system API also helps with creating client-only route. Previously, to access dynamic content that isn’t known to Gatsby at build time,(Which is referred to as client-only routes) you would have to create a route with one or more dynamic segments to query data from a server in order to render your page.

For example, to show a user a personalized settings page, in order to edit a user, you might want a route like /user/:id to fetch the data for whatever id is passed into the URL. You can now use square brackets ([ ]) in the file path to mark any dynamic segments of the URL.

This means src/pages/users/[id].js would look like this /users/:id. Gatsby also supports splat routes, learn more about this in the documentation

Conclusion

There you have it, folks. I believe that with a few improvements to other pain points of Gatsby, some of the processes will be less stressful.