Building Rise of the Robots with Gatsby and Contentful

Hi there! I recently built Rise of the Robots using Gatsby + Rive to demonstrate how Jamstack creativity and performance can co-exist without sacrificing page load speeds.

I wrote a blog post on the Gatsby Blog that dives a little deeper into the techniques used to build the site and have included some actionable know-how you can use in your next Gatsby project. Below are some links to the original post, the demo, and the open-source repo. 

In this blog post, however, I'd like to expand on how I used Contentful to drive the content and demonstrate the speed and flexibility of building a Gatsby site powered by Contentful.

Rise of the Robots blog, demo, and repo

✏️ https://www.gatsbyjs.com/blog/building-rise-of-the-robots/

🚀 https://www.gatsbyjs.com/demos/rise-of-the-robots/

⚙️ https://github.com/PaulieScanlon/rise-of-the-robots

Here’s a video, it’s just under six minutes and it’ll walk you through, in real time, how to build a Gatsby site from scratch and implement Contentful as the CMS using the same content model I used in the demo site.

Step-by-Step: Building a Gatsby site with Contentful

Before you start

You’ll need to have at least Node version 14 installed locally and have a Contentful account set up. You might also want to go ahead and install the Contentful CLI, and check you can login via your terminal

I’ve also prepared a repo, which you can use for reference if you’d like to follow along with the video. 

⚙️ Main

https://github.com/PaulieScanlon/gatsby-contentful-rotr-clone

If you’d like to jump ahead, the finished version can be found on a branch named finished. 

🌱 Finished Branch:

https://github.com/PaulieScanlon/gatsby-contentful-rotr-clone/tree/finished

1. Initialize npm & add dependencies

In this step I initialize npm using the following, which creates a default package.json.

Next, I install the following dependencies. Gatsby has x2 peer dependencies, react, and react-dom. (I’ve used yarn in the video, npm will work just as well.)

2. Add scripts to package.json

Gatsby has x4 scripts. They are as follows:

  • gatsby develop — runs the development server and GraphiQL explorer.

  • gatsby build — creates a production ready static site.

  • gatsby clean — deletes the .cache and public directories on disk.

  • gatsby serve — starts an http server to preview the built site.

You can see the complete package.json used in the video on the finished branch.

3. Add Contentful workspace

Go ahead and create a new empty space in the Contentful UI and fill out the required fields. You’ll be populating this space with the real data from my demo in the next step.

4. Contentful space import

This next step requires you have the Contentful CLI installed. You can read more about how to do this in the Contentful docs: Installing the Contentful CLI.

You’ll also need to have added my rotr-export.json file to your project. You can grab that from this Gist: PaulieScanlon/rotr-export.json or the main or finished branch from the repo as mentioned above.

Note: Once you’ve imported the .json file to Contentful, you can delete it from your project.  

You should now be seeing all of the data in the Contentful UI in the Content section. 

5. Add gatsby-source-contentful 

This is one of many officially maintained Gatsby plugins. If you’re ever in doubt as to who maintains a Gatsby plugin, check the username on GitHub: Here’s the repo for gatsby-source-contentful, you can also access the README from our plugin library page

Install the plugin.

6. Add to gatsby-config.js

To use any Gatsby plugin, you add it to the plugins array within gatsby-config.js.

Here’s a snippet from the docs which I've referenced in the video.

7. Add API keys

You can find the API keys for your space in the Contentful UI under: Settings > API Keys

Add both the Space ID and Access Token to the plugin’s options.

Note: the Space ID and Access Token used in the above snippet and video have been revoked, just in case you try to use them.

8. Add peer dependencies

Gatsby-source-contentful has x2 dependencies to handle image processing. Attempting to run the development server without these dependencies installed will result in an error. 

Install both peer dependencies.

Add both to the plugin’s array in gatsby-config.js.

9. Dev server and GraphiQL

Technically speaking, at this point you’re done. That’s everything you need to do to hook up Gatsby with Contentful… but, there’s a little more required to display data on a page. 

To run the development server, type the below in your terminal.

Then open up GraphiQL (pronounced graphical), using the link in your terminal or by visiting: http://localhost:8000/__graphql

What you’re looking at here is Gatsby’s Data Layer. GraphiQL is a graphical representation of all the data that has been sourced from Contentful using the plugin and it’s stored temporarily for development purposes in Gatsby’s Data Layer until you decide what to query and use in your site. 

Data queried via GraphQL is what actually gets “baked” into your site, and all this combined creates what we know today as a static site.  

If you’re not familiar with GraphQL, don’t worry, you don’t really need to be. 

You can explore the entire Data Layer by clicking around on the field names. GraphiQL will then construct the query for you. 

Using the Play button, you can run the query to see what data will be returned. I’d recommend clicking around to see what data is available to you, before you decide what you’d like to use in your site.

10. Create page query

There is however, definitely one part of this data you will want to use, and that’s ContentfulPage. 

To manually create pages with Gatsby you can create a file called some-page.js and save it under src/pages. This would result in an HTML page being created and available on  www.your-domain.com/some-page.

A page is just a normal React component that uses export default.

However, Gatsby can also create pages programmatically using the File System Route API, (FS Routes). FS Routes will dynamically turn a collection of data into actual HTML pages. 

Looking at the Contentful UI you’ll notice there’s x2 pages. “/” which is the index or default page, and “/404”, which is the Not Found page. 

Contentful UI showing two pages

Inside each page is a field called url

Contentful UI showing url field

You can use this field name as a collection route

To programmatically create pages from data, you can escape the field name(s) using curly braces, e.g., {contentfulPage.url}.js. This file can now be considered a page template. 

Gatsby will now create a page for each Contentful type called “Page” and will use the “url” field to form the route or slug.

Example:

  • /

  • /404

The more page(s) you add to Contentful, the more pages Gatsby will create. 

With a page created in Contentful, you can query the data specific to that page using GraphQL. 

The id is passed by Gatsby to the GraphQL query automatically, so only data for the “/” page, for example, ends up in the static/built index page. All other data that’s not queried won’t be passed onto the page. It’s how we keep page load speeds blazing fast! 

In the above snippet and video, all I'm doing in the page template is querying the sections and their __typename, and passing the data back to the component via the data parameter. I then return the data in Jsx using an HTML <pre> element. Not overly exciting, hey?

That’s everything from the video and in this next bit I'll show you how I've queried data for each section, abstracted each section into its own component, and I'll introduce a new querying method called useStaticQuery. If you’d like to read more about content querying, here’s a post from the Gatsby Blog: Content Querying with Gatsby + Contentful

However, if you’re familiar with React hooks, you’ll feel right at home! 

Next Steps: Modify the page template

The changes made here are to use .map to iterate over each “section” and using the __typename, which is passed into the getSection function, I can determine which component to return. 

In the above snippet I’ve created a new component called <HeroComponent />

In the switch statement, if the __typename equals ContentfulHeroSection, I return the <HeroComponent />, if it’s not, I return nothing.

The hero component

In the <HeroSection /> component I'm using Gatsby’s useStaticQuery hook to query a few fields from the data layer.

You can see all the data available if you have a little click around in GraphiQL.

Image of GraphiQL wit selected data fields

Then, once you’re happy with the query, hit the play button to see what will be returned, then using either a bit of copying and pasting or the Code Exporter, you can transfer the query into your code and return it with appropriate HTML elements. 

You may notice the eventDetails.raw field returns rather a lot of computery looking jibby-jabber. It does, but this is how Contentful’s Rich Text editor returns data. Don’t worry, here's another post from the Gatsby blog explaining how all that good stuff works: How To Use The Contentful Rich Text Field with Gatsby.

For each of the other sections used in the Rise of the Robots demo site, I've followed the same pattern as I did with the <HeroComponent />. I prefer to abstract these queries as they can become quite large, and I'm of the opinion that: 

Code that is edited together, should live together. 

And that just about wraps things up. I’ve made a note of some other helpful blog posts below, but if you'd like to discuss anything covered in this post, please come find me on Twitter: @PaulieScanlon

Further Reading

About the author

Don't miss the latest

Get updates in your inbox
Discover new insights from the Contentful developer community each month.
add-circle arrow-right remove style-two-pin-marker subtract-circle