Skip to main content

File System Route API

This page documents the APIs and conventions available with a file system based routing API, a suite of new APIs and conventions to make the file system the primary way of creating pages. While the createPage Node API won’t go away you should be able to accomplish most common tasks with this file-based API.

For now, these features are marked as experimental and require a flag to utilize. Add the following flag when using gatsby develop and gatsby build:

Or in the scripts section of your package.json:

Note: If you’re on Windows you should install cross-env and prepend your scripts, e.g.:

Files created in src/pages were always automatically converted to single-page routes, now you’re also able to define client-only and dynamic collection-based routes there.

A complete example using all options below can be found in Gatsby’s “examples” folder.

Creating collection pages

You can create multiple pages from a model based on the collection of nodes within it. To do that, use curly braces ({ }) to signify dynamic URL segments that relate to a field within the node. There is some special logic that can happen in here. Here are a few examples:

  • src/pages/products/{}.js => /products/burger
  • src/pages/products/{Product.fields__sku}.js => /products/001923
  • src/pages/blog/{MarkdownRemark.parent__(File)__name}.js => /blog/learning-gatsby

Gatsby uses the content within the curly braces to generate GraphQL queries to retrieve the nodes that should be built for a given collection. For example:

src/pages/products/{}.js generates the following query:

src/pages/products/{Product.fields__sku}.js generates the following query:

src/pages/blog/{MarkdownRemark.parent__(File)__name}.js generates the following query:

This is the query that Gatsby uses to grab all the nodes and create a page for each of them. Gatsby also adds id to every query automatically to simplify how to integrate with page queries.

Component implementation

Page components act the exact same way. Gatsby will create an instance of it for each node it finds in it’s querying. In the component itself (e.g. src/pages/products/{}.js) you’re then able to access the name via props and as a variable in the GraphQL query. However, we recommend filtering by id as this is the fastest way to filter.

If you need to customize the query used for collecting the nodes, that can be done with a special export. Much akin to page queries. In the example below you filter out every product that is of type “Burger” for the collection route:

Creating client-only routes

Use client-only routes if you have dynamic data that does not live in Gatsby. This might be something like a user settings page, or some other dynamic content that isn’t known to Gatsby at build time. In these situations, you will usually create a route with one or more dynamic segments to query data from a server in order to render your page.

For example, 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.

  • src/pages/users/[id].js => /users/:id
  • src/pages/users/[id]/group/[groupId].js => /users/:id/group/:groupId

Gatsby also supports splat routes, which are routes that will match anything after the splat. These are less common, but still have use cases. As an example, suppose that you are rendering images from S3 and the URL is actually the key to the asset in AWS. Here is how you might create your file:

  • src/pages/image/[...awsKey].js => /image/*awsKey
  • src/pages/image/[...].js => /image/*

Three periods ... mark a page as a splat route. Optionally, you can name the splat as well, which has the benefit of naming the key of the property that your component receives. The dynamic segment of the file name (the part between the square brackets) will be filled in and provided to your components on a props.params object. For example:

Routing and linking

Gatsby “slugifies” every route that gets created from collection pages. When you want to link to one of those pages, it may not always be clear how to construct the URL from scratch.

To address this issue, 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. Here is an example of how this works:

Assume that a Product model is used in two pages:

  • src/pages/products/{}.js
  • src/pages/discounts/{}.js

If you wanted to link to the products/{} route from your home page, you would have a component like this:

Example use cases

Collection route + fallback

By using a combination of a collection route with a client only route, you can create a great experience when a user tries to visit a URL from the collection route that doesn’t exist for the collection item. Consider these two file paths:

  • src/pages/products/{}.js
  • src/pages/products/[name].js

If the user visits a product that wasn’t built from the data in your site, they will hit the client-only route, which can be used to show the user that the product doesn’t exist.

Edit this page on GitHub