Programmatically create pages from data
In the previous tutorial, you created a nice index page that queries markdown files and produces a list of blog post titles and excerpts. But you don’t want to just see excerpts, you want actual pages for your markdown files.
You could continue to create pages by placing React components in
src/pages. However, you’ll now learn how to programmatically create pages from data. Gatsby is not limited to making pages from files like many static site generators. Gatsby lets you use GraphQL to query your data and map the query results to pages—all at build time. This is a really powerful idea. You’ll be exploring its implications and ways to use it for the remainder of this part of the tutorial.
Let’s get started.
A ‘slug’ is the unique identifying part of a web address, such as the
/docs/tutorial/part-seven part of the page
It is also referred to as the ‘path’ but this tutorial will use the term ‘slug’ for consistency.
Creating new pages has two steps:
- Generate the “path” or “slug” for the page.
- Create the page.
Note: Often data sources will directly provide a slug or pathname for content — when working with one of those systems (e.g. a CMS), you don’t need to create the slugs yourself as you do with markdown files.
We do our best to make Gatsby APIs simple to implement. To implement an API, you export a function with the name of the API from
So, here’s where you’ll do that. In the root of your site, create a file named
gatsby-node.js. Then add the following.
onCreateNode function will be called by Gatsby whenever a new node is created (or updated).
Stop and restart the development server. As you do, you’ll see quite a few newly created nodes get logged to the terminal console.
In the next section, you will use this API to add slugs for your Markdown pages to
Change your function so it now only logs
You want to use each markdown file name to create the page slug. So
pandas-and-bananas.md will become
/pandas-and-bananas/. But how do you get the file name from the
MarkdownRemark node? To get it, you need to traverse the “node graph” to its parent
File node, as
File nodes contain data you need about files on disk. To do that, you’ll use the
getNode() helper. Add it to
onCreateNode’s function parameters, and call it to get the file node:
After restarting your development server, you should see the relative paths for your two markdown files print to the terminal screen.
Now you’ll have to create slugs. As the logic for creating slugs from file names can get tricky, the
gatsby-source-filesystem plugin ships with a function for creating slugs. Let’s use that.
The function handles finding the parent
File node along with creating the slug. Run the development server again and you should see logged to the terminal two slugs, one for each markdown file.
Now you can add your new slugs directly onto the
MarkdownRemark nodes. This is powerful, as any data you add to nodes is available to query later with GraphQL. So, it’ll be easy to get the slug when it comes time to create the pages.
To do so, you’ll use a function passed to your API implementation called
createNodeField. This function allows you to create additional fields on nodes created by other plugins. Only the original creator of a node can directly modify the node—all other plugins (including your
gatsby-node.js) must use this function to create additional fields.
Restart the development server and open or refresh GraphiQL. Then run this GraphQL query to see your new slugs.
Now that the slugs are created, you can create the pages.
In the same
gatsby-node.js file, add the following.
You’ve added an implementation of the
createPages API which Gatsby calls so plugins can add pages.
As mentioned in the intro to this part of the tutorial, the steps to programmatically creating pages are:
- Query data with GraphQL
- Map the query results to pages
The above code is the first step for creating pages from your markdown as you’re using the supplied
graphql function to query the markdown slugs you created. Then you’re logging out the result of the query which should look like:
You need one additional thing beyond a slug to create pages: a page template component. Like everything in Gatsby, programmatic pages are powered by React components. When creating a page, you need to specify which component to use.
Create a directory at
src/templates, and then add the following in a file named
Restart the development server and your pages will be created! An easy way to find new pages you create while developing is to go to a random path where Gatsby will helpfully show you a list of pages on the site. If you go to
http://localhost:8000/sdf, you’ll see the new pages you created.
Visit one of them and you see:
Which is a bit boring and not what you want. Now you can pull in data from your markdown post. Change
The last step is to link to your new pages from the index page.
src/pages/index.js, query for your markdown slugs, and create links.
And there you go! A working, albeit small, blog!
Try playing more with the site. Try adding some more markdown files. Explore querying other data from the
MarkdownRemark nodes and adding them to the front page or blog posts pages.
In this part of the tutorial, you’ve learned the foundations of building with Gatsby’s data layer. You’ve learned how to source and transform data using plugins, how to use GraphQL to map data to pages, and then how to build page template components where you query for data for each page.
Now that you’ve built a Gatsby site, you’re ready for the final tutorial where you’ll prepare your site to go live!
From there, you can:
- Share your Gatsby site on Twitter and see what other people have created by searching for #gatsbytutorial! Make sure to mention @GatsbyJS in your tweet and include the hashtag
- You could take a look at some example sites
- Explore more plugins
- See what other people are building with Gatsby
- Check out the documentation on Gatsby’s APIs, nodes, or GraphQL