What you need to know about Gatsby’s File System Route API

Thilo Maier •
Last modified:

The new File System Route API in Gatsby takes inspiration from dynamic routes in Next.js. The main difference is that the File System API retrieves data from Gatsby’s GraphQL layer, while in Next.js for dynamic routes you have to write custom code to retrieve data from any data source that can be tapped with JavaScript.

Programmatic page generation with gatsby-node.js

Gatsby Node APIs used to be the only way to generate pages programmatically inside a gatsby-node.js. You can think of Gatsby Node APIs as a collection of hooks with which you can hook into Gatsby’s build process to manipulate nodes in Gatsby’s GraphQL layer and to generate pages programmatically. In my Gatsby themes I usually create the following API functions inside gatsby-node.js:

  • onCreateNode is called when a new node is created. You can use this function to derive new nodes from existing nodes or to add fields to existing nodes.
  • createPages is called after the GraphQL layer is ready. You can query nodes and then create pages from queried nodes.
  • createSchemaCustomization is called to override Gatsby’s schema inference. This is called schema customization. You do not have to customize your GraphQL schema. Schema inference is robust and works well. In my Gatbsy themes, I customize the schema and introduce custom types to simplify GraphQL queries.

A typical sequence for programmatic page generation looks like this:

  1. Source nodes from various data sources.
  2. Transform nodes and derive new nodes.
  3. Generate pages from a subset of nodes.

This involves two types of GraphQL queries:

  1. A node selection query, executed inside createPages, to select nodes from which pages should be generated. If you are familiar with Next.js, this is the equivalent of getStaticPaths.
  2. A page query is exported from a template and run during page generation. This is the equivalent of getStaticProps in Next.js.

The File System Route API does not make gatsby-node.js obsolete. It is an alternative API for programmatic page generation that complements gatsby-node.js and can replace it in certain scenarios. With the File System Route API, you trade in full control and complexity for a more simple but more opinionated approach that covers many common scenarios, but not all.

Before we dive into the File System Route API, let’s recall that directory src/pages has special routing powers in Gatsby. Any React component in this directory is turned into a page whose route corresponds to the file path. This is called file-system-based routing.

Generating pages for an entire collection with collection routes

With the File System Route API, you can place React components in src/pages that have additional information encoded in their filename and/or pathname. Component src/pages/posts/{Post.title}.js with {} notation in the filename triggers page generation for each GraphQL Post node. {Post.title} is interpreted as a node selection query to select a collection of nodes from which to create pages and their routes. In this example, Gatsby creates this query under the hood

allPost {
  nodes {
    id
    title
  }
}

and generates a page for each id using the default export of file {Post.title}.js, which also has to export a page query that receives id as query parameter.

As a convention, the value between {}, in this case, Post.title, is slugified and used as part of the route. For example, title What you need to know about Gatsby’s File System Route API would result in what-you-need-to-know-about-gatsbys-file-system-route-api. And the route of the generated page is

/posts/what-you-need-to-know-about-gatsbys-file-system-route-api

which is the relative path to {Post.title}.js inside src/pages plus the slugified title.

Client-only routes without generating pages

You can also use [] notation with the File System Route API to create client-only routes. Gatsby does not generate pages for client-only routes, i.e. client-only routes cannot be used as entry points for the site. For example, file src/pages/users/[id].js results in client-only routes following this pattern: /users/:id (:id is the route paramters notation from Express). A params object with prop id is passed into the React component available as default export in file [id].js. If you know Next.js this should sound familiar.

A common use case for [] notation in Gatsby is a fallback for a collection route. For example, you could complement src/pages/products/{Product.name}.js with src/pages/products/[name].js. In this scneario, the {} collection route takes precedence and for everything else the [] client-only route is used.

Catch-all routes

With the File System Route API you can use [] notation to create a catch-all route and delegate all routes in a subtree of your site to a custom React app. For example, /src/pages/dashboard/[...].js will handle all /dashboard/* routes. You can access sub-routes like this

function App(props) {
  const splat = props.params[*]
}

and pass them into a router like React Router.

5 takeaways from Gatsby’s File System Route API

  • The File System Route API in Gatsby does not make gatsby-node.js obsolete, but rather complements it and can replace it in certain use cases.
  • {} notation adapts the concept of dynamic routes or file-system-based routing to Gatsby’s GraphQL layer, which is Gatsby’s unique selling point to access data from various sources. There are more types of GraphQL queries that can be expressed with {} notation than covered in this post. Check the Gatsby File System Route API documentation.
  • [] notation adds an API that is similar to dynamic routes in Next.js, but for client-side routes only.
  • The File System Route API can help reduce the lines of code required for programmatic page generation. But because you need to encode GraphQL queries in filenames, it feels a little opinionated. I would expect most Gatsby sites to go for a mixed approach for programmatic page generation, i.e. reach for the File System Route API for simple scenarios and for gatsby-node.js for more complex ones.
  • If you are comfortable using gatsby-node.js, there is no need to migrate anything to the File System Route API.

Links