Programmatically create pages from data

This tutorial is part of a series about Gatsby’s data layer. Make sure you’ve gone through part 4, part 5, and part 6 before continuing here.

What’s in this tutorial?

In the previous tutorial, you created a nice index page that queries markdownfiles and produces a list of blog post titles and excerpts. But you don’t want to just see excerpts, you want actual pages for yourmarkdown files.

You could continue to create pages by placing React components in src/pages. However, you’llnow learn how to programmatically create pages from data. Gatsby is not_limited to making pages from files like many static site generators. Gatsby letsyou use GraphQL to query your _data and map the query results to pages—all at buildtime. This is a really powerful idea. You’ll be exploring its implications andways to use it for the remainder of this part of the tutorial.

Let’s get started.

Creating slugs for pages

A ‘slug’ is the unique identifying part of a web address,such as the /tutorial/part-seven part of the page https://www.gatsbyjs.org/tutorial/part-seven/.

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.

To create your markdown pages, you’ll learn to use two Gatsby APIs:onCreateNode andcreatePages. These are two workhorse APIsyou’ll see used in many sites and plugins.

We do our best to make Gatsby APIs simple to implement. To implement an API, you export a functionwith the name of the API from gatsby-node.js.

So, here’s where you’ll do that. In the root of your site, create a file namedgatsby-node.js. Then add the following.

This 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 newlycreated nodes get logged to the terminal console.

In the next section, you will use this API to add slugs for your Markdown pages to MarkdownRemarknodes.

Change your function so it now only logs MarkdownRemark nodes.

You want to use each markdown file name to create the page slug. Sopandas-and-bananas.md will become /pandas-and-bananas/. But how do you getthe 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 youneed about files on disk. To do that, modify your function again:

After restarting your development server, you should see the relative paths for your two markdownfiles print to the terminal screen.

markdown-relative-path

Now you’ll have to create slugs. As the logic for creating slugs from file names can gettricky, the gatsby-source-filesystem plugin ships with a function for creatingslugs. Let’s use that.

The function handles finding the parent File node along with creating theslug. Run the development server again and you should see logged to the terminaltwo slugs, one for each markdown file.

Now you can add your new slugs directly onto the MarkdownRemark nodes. This ispowerful, 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 calledcreateNodeField. This functionallows you to create additional fields on nodes created by other plugins. Onlythe original creator of a node can directly modify the node—all other plugins(including your gatsby-node.js) must use this function to create additionalfields.

Restart the development server and open or refresh GraphiQL. Then run thisGraphQL query to see your new slugs.

Now that the slugs are created, you can create the pages.

Creating pages

In the same gatsby-node.js file, add the following.

You’ve added an implementation of thecreatePages API which Gatsby calls so plugins can addpages.

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’reusing 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:

query-markdown-slugs

You need one additional thing beyond a slug to create pages: a page templatecomponent. Like everything in Gatsby, programmatic pages are powered by Reactcomponents. 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 namedsrc/templates/blog-post.js.

Then update gatsby-node.js

Restart the development server and your pages will be created! An easy way tofind new pages you create while developing is to go to a random path whereGatsby will helpfully show you a list of pages on the site. If you go tohttp://localhost:8000/sdf, you’ll see the new pages you created.

new-pages

Visit one of them and you see:

hello-world-blog-post

Which is a bit boring and not what you want. Now you can pull in data from your markdown post. Changesrc/templates/blog-post.js to:

And…

blog-post

Sweet!

The last step is to link to your new pages from the index page.

Return to src/pages/index.js, query for your markdown slugs, and createlinks.

And there you go! A working, albeit small, blog!

Challenge

Try playing more with the site. Try adding some more markdown files. Explorequerying other data from the MarkdownRemark nodes and adding them to thefront page or blog posts pages.

In this part of the tutorial, you’ve learned the foundations of building withGatsby’s data layer. You’ve learned how to source and transform data usingplugins, how to use GraphQL to map data to pages, and then how to build pagetemplate components where you query for data for each page.

What’s coming next?

Now that you’ve built a Gatsby site, where do you go next?