I just implemented a very simple version of Gatsby’s new File System Route API* and I have to say, I love it.
Until now, the only way to dynamically create pages in Gatsby has been to use the createPages API inside of the gatsby-node.js file. While this works really well, and is still something you will have to use when you have have more complex conditions (e.g. if you only want to create pages for a subset of blogposts) the new File System Route API really simplifies things for most of page-creation use cases such as blog posts or in my case, photo albums.
Here’s the gist:
I have a bunch of photo albums that I created via my CMS. Which CMS I used isn’t important here (cough cough it was Sanity which you should definitely check out). What is important is how I queried for my blogposts using Gatsby’s GraphQL API. Your data will be structured differently, but this example will give you a sense of things:
query AlbumsQuery {
allSanityAlbums {
edges {
node {
title
slug {
current
}
}
}
}
}
I’m not going to go into the fine details of how this API works, I just want to show you that it does, and it’s pretty slick.
Ok, so now I want Gatsby to somehow loop through each of the SanityAlbums using the “edges” array that’s returned by the above query, then have Gatsby create pages for each album, or “node” and finally use slug.current as the page’s slug.
Looking at my Gatsby files in VSCode, I have created a folder called “Albums”, and inside that folder I create a React component file using a special syntax for the filename, ie. {SanityAlbums.slugcurrent}.js
This filename will result in a page with the following url:
Notice that I nested the file in the albums directory, which provides the url with the /albums/ structure, but you could just as easily make a top-level page by skipping that step and putting the file directly in the pages directory.
Ok, you have to admit that the filename looks pretty weird. Curly brackets? Take a breath ‘cause those curly brackets help make the magic happen. This filename tells Gatsby, “For each of my “SanityAlbums”, create a new page using the component in this file and set the slug to the value of slug.current. The double underscore is what indicates that we’re using a child property of SanityAlbums.slug. Why don’t we just write it as {SanityAlbums.slug.current}.js you ask? No idea but it works!
Inside the file is a simple React component that is going to render on each of the pages:
import React from “react”
const Album = ({ data }) => {
return <div>{data.sanityAlbums.title}</div>
}
export const query = GraphQL`
query($id: String!) {
sanityAlbums(id: { eq: $id }) {
title
}
}
`
export default Album
Gatsby automatically queries for the id for each of the nodes, so we can use it in our component’s Page Query in order to extract the data that we want to use in the component. To keep things simple, I have only queried for the page title but you can access any of your data here.
And that is seriously it! Honestly, just save your file and your new pages should be live. By adding this one file and a few lines of code I now have individual pages for each of my photo albums. Amazing.
Keep in mind that there are still plenty of use-cases when the createPages API is required, so this isn’t a complete replacement for that but it is sure a great way to get things built even faster.
More more info on the API, check out the Gatsby docs. The folks at Gatsby also have some really great example code for this .
Now go try it out and let me know what you think!
EDIT: To use this feature, you'll need to be using Gatsby version 2.26.0 or later.
EDIT: (Feb 17, 2021) A drawback of this approach is that you cannot currently pass custom data to the page via pageContext like you can with the createPages API. If you need to do that because, for example, you want to fetch data from an external data source (i.e. not Gatsby's graphQL layer) at build time, you should use the createPages API for now.
Top comments (0)