File System Route API
Examples
Use the File System Route API when you want to create dynamic pages e.g. to create individual blog post pages for your blog.
You should be able to accomplish most common tasks with this file-based API. If you want more control over the page creation you should use thecreatePages API.
Dynamic pages can be created from collections in Gatsby’sGraphQL data layer and to createclient-only routes.
A complete example showcasing all options can be found inGatsby’s examples folder.
Collection routes
Imagine a Gatsby project that sources aproduct.yaml file and multiple Markdown blog posts. At build time, Gatsby will automaticallyinfer the fields and create multiplenodes for both types (Product andMarkdownRemark).
To create collection routes, use curly braces ({ }) in your filenames to signify dynamic URL segments that relate to a field within the node. Here are a few examples:
src/pages/products/{Product.name}.jswill generate a route like/products/burgersrc/pages/products/{Product.fields__sku}.jswill generate a route like/products/001923src/pages/blog/{MarkdownRemark.parent__(File)__name}.jswill generate a route like/blog/learning-gatsby
Gatsby creates a page for each node in a collection route. So if you have three markdown files that are blog posts, Gatsby will create the three pages from a collection route. As you add and remove markdown files, Gatsby will add and remove pages.
Collection routes can be created for any GraphQL data type. Creating new collection routes in Gatsby is a processof adding a source plugin, use GraphiQL to identify the type and field to construct the route file name, and then code the route component.
Syntax (collection routes)
There are some general syntax requirements when using collection routes:
- Dynamic segments of file paths must start and end with curly braces (
{ }). - Types are case-sensitive (e.g.
MarkdownRemarkorcontentfulMyContentType). Check GraphiQL for the correct names. - Dynamic segments must include both a type and a field e.g.
{Type.field}or{BlogPost.slug}.
Nested routes
You can use dynamic segments multiple times in a path. For example, you might want to nest product names within its product category. For example:
src/pages/products/{Product.category}/{Product.name}.jswill generate a route like/products/toys/fidget-spinnersrc/pages/products/{Product.category}/{Product.name}/{Product.color}.jswill generate a route like/products/toys/fidget-spinner/red
Field syntax
Dot notation
Using. you signify that you want to access a field on a node of a type.
src/pages/products/{Product.name}.js generates the following query:
Underscore notation
Using__ (double underscore) you signify that you want to access a nested field on a node.
src/pages/products/{Product.fields__sku}.js generates the following query:
You can nest as deep as necessary, e.g.src/pages/products/{Product.fields__date__createdAt}.js generates the following query:
Parentheses notation
Using( ) you signify that you want to access aGraphQL union type. This is often possible with types that Gatsby creates for you. For example,MarkdownRemark always hasFile as a parent type, and thus you can also access fields from theFile node. You can use this multiple levels deep, too, e.g.src/pages/blog/{Post.parent__(MarkdownRemark)__parent__(File)__name}.js.
src/pages/blog/{MarkdownRemark.parent__(File)__name}.js generates the following query:
Collection Route Components
Collection route components are passed two dynamic variables. Theid of each page’s node and theURL path asparams. The params is passed to the component asprops.params and the id asprops.pageContext.id.
Both are also passed as variables to the component’s GraphQL query so you can query fields from the node. Page querying, including the use of variables, is explained in more depth inquerying data in pages with GraphQL.
For example:
For the pagesrc/pages/{Product.name}/{Product.coupon}.js you’d haveprops.params.name andprops.params.coupon available inside{Product.coupon}.js.
If you need to want to create pages for only some nodes in a collection (e.g. filtering out any product of type"Food") or customize the variables passed to the query, you should use thecreatePages API instead as File System Route API doesn’t support this at the moment.
Routing and linking
Gatsby “slugifies” every route that gets created from collection pages (by usingsindresorhus/slugify). Or in other words: If you have a route calledsrc/pages/wholesome/{Animal.slogan}.js whereslogan isI ♥ Dogs the final URL will be/wholesome/i-love-dogs. Gatsby will convert the field into a human-readable URL format while stripping it of invalid characters. You can configureslugify by adjustinggatsby-plugin-page-creator for yoursrc/pages path.
When you want to link to a collection route page, it may not always be clear how to construct the URL from scratch.
To address this issue, Gatsby automatically includes agatsbyPath field on every type used by collection pages. ThegatsbyPath field must take an argument of thefilePath it is trying to resolve. This is necessary because it’s possible that one type is used in multiple collection pages.
There are some general syntax requirements when using thefilePath argument:
- The path must be an absolute path (starting with a
/). - You must omit the file extension.
- You must omit the
src/pagesprefix. - Your path must not include
index.
gatsbyPath example
Assume that aProduct type is used in two pages:
src/pages/products/{Product.name}.jssrc/pages/discounts/{Product.name}.js
If you wanted to link to theproducts/{Product.name} anddiscounts/{Product.name} routes from your home page, you would have a component like this:
By usingaliasing you can usegatsbyPath multiple times.
Creating client-only routes
Useclient-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.
Syntax (client-only routes)
You can use square brackets ([ ]) in the file path to mark any dynamic segments of the URL. For example, in order to edit a user, you might want a route like/user/:id to fetch the data for whateverid is passed into the URL.
src/pages/users/[id].jswill generate a route like/users/:idsrc/pages/users/[id]/group/[groupId].jswill generate a route like/users/:id/group/:groupId
Splat routes
Gatsby also supportssplat (or wildcard) routes, which are routes that will matchanything after the splat. These are less common, but still have use cases. Use three periods in square brackets ([...]) in a file path to mark a page as a splat route. You can also name the parameter your page receives by adding a name after the three periods ([...myNameKey]).
As an example, suppose that you are rendering images fromS3 and the URL is actually the key to the asset in AWS. Here is how you might create your file:
src/pages/image/[...].jswill generate a route like/image/*.*is accessible in your page’s received properties with the key name*.src/pages/image/[...awsKey].jswill generate a route like/image/*awsKey.*awsKeyis accessible in your page’s received properties with the key nameawsKey.
Splat routes may not live in the same directory as regular client only routes.
Examples
The dynamic segment of the file name (the part between the square brackets) will be filled in and provided to your components on aprops.params object. For example:
config function
Inside a File System Route template you can export an async function calledconfig. You can use this function to:
- Mark the page as deferred or not (seeDeferred Static Generation API reference)
Inside your template:
When you export an asyncconfig function Gatsby will evaluate the returned object and optionally run any GraphQL queries defined inside the outer function. You can’t run GraphQL queries inside the inner function.
Theparams parameter is an object that contains the URL path, seeexplanation above.
The inner function ofconfig can return an object with one key:
defer: Boolean of whether the page should be marked as deferred or not
Read theDeferred Static Generation guide to see a real-world example.
Example use cases
Have a look at theroute-api example for more detail.
Collection route + fallback
By using a combination of a collection route with a client-only route, you can create a seamless experience when a user tries to visit a URL from the collection route that doesn’t exist (yet) for the collection item. Consider these two file paths:
src/pages/products/{Product.name}.js(collection route)src/pages/products/[name].js(client-only route, fallback)
The collection route will create all available product pages at the time of thebuild. If you’re adding a new product you want to link to but only periodically building your site, you’ll need a fallback. By using a client-only route as a fallback you then can load the necessary information for the product on the client until you re-built your site.
Similarly, the fallback page could also be used for when a product doesn’t exist and you want to show some helpful information (like a 404 page).
Using one template for multiple routes
By placing the template/view for your routes into a reusable component you can display the same information under different routes. Take this example:
You want to display product information which is both accessible by name and SKU but has the same design. Create two file paths first:
src/pages/products/{Product.name}.jssrc/pages/products/{Product.meta__sku}.js
Create a view component atsrc/view/product-view.js that takes in aproduct prop. Use that component in both collection routes, e.g.:
You can copy the same code to thesrc/pages/products/{Product.meta__sku}.js file.
Purely client-only app
If you want your Gatsby app to be 100% client-only, you can create a file atsrc/pages/[...].js to catch all requests. See theclient-only-paths example for more detail.