GatsbyContentful

Incorporate a Headless CMS


Prerequisite


I'm going to assume that you are already familiar with Gatsby and that you already have it set up. This post is meant for developers who want to integrate a headless CMS into their site. So with that out of the way, let's get started!

Create Contentful account


In order to get started, we need to create an account in Contentful, which can be done free when selecting the basic path recommended for developers. Once you have created your free account, you then need to create a new space. A space is a collection of content or a place where you can store your blogs. After you have created a new space, you can now create a structure of your blog and then create content based on that structure by clicking on the tabs "Content Model" and "Content."

Content Model

We will first go to the tab "Content Model" to create the structure of the blog. This is where we will define data types such as title, author, published date, etc. In this section let's add a content type. Since the goal is to add blogs to your site, you can set the name to "Blog Post" or something similar, up to you. For the description you can add whatever you want. Now click the create button and then we can get started on adding fields to the Blog model.

You should at this point after you've created the model:

5nxn7CpAup8OVGtbumkRRf

When you add a field, you're going to see a variety of types. Let's first start off with a basic template and from there you can then decide to add more. All blog posts should have a name and that is going to be represented as the "Text" field type. Write the name of the blog post and then click on the create button. You have now created a field type for the blog model. You can configure it to add validations or change its appearance but we won't be going over that so I'll let you mess around with it on your own time.

Let's add a few more field types. Since we need to dynamically generate a new page each time a blog post is created, we'll need to create a slug field. Good thing is that it'll use the exact same field type as the blog post name. Finally, let's add the body of the blog post which will be represented as the "Rich Text" field type. Again, if you want to add more field types, feel free to do so.

Now that we have created a model for our Blog, let's go over to the "Content" tab to create instances of the blog.

Content

In this section, click on the add entry button and in there, you'll see the field types in which you have created for the blog model. Add in the appropriate entries for each fields and then click on publish, to publish your very first blog post in Contentful. And that is it, if you want to add more blog posts, then all you have to do is add another entry and publish again. Now lets head over to your Gatsby code to configure Contentful.

Configure Contentful


First step in integrating Contentful to your Gatsby site is to install the Contentful plugin. Information of the plugin can be found in Gatsby Contentful Plugin. In your terminal, run this command:

npm install gatsby-source-contentful

Once that has finished running, head over to the gatsby.config file to add the following:

module.exports = { plugins: [{ resolve: `gatsby-source-contentful`, options: { spaceId: process.env.CONTENTFUL_SPACE_ID, accessToken: process.env.CONTENTFUL_ACCESS_TOKEN }, }] }

Your space ID and access token can be found in Contentful, so head back over there and go to the settings tab. Under the settings tab, go to API keys. If there is no API keys listed, go ahead a create a new one. It will show your space ID and access token. You want to copy those values so you can add it to your .env.development file in your Gatsby project. If you don't have a .env.development file, create one, it should be located in the root directory of the Gatsby project. In the file set up your code like this:

CONTENTFUL_SPACE_ID=your_space_id CONTENTFUL_ACCESS_TOKEN=your_access_token

Do not wrap your space ID or access token in quotes, just add it in as it is. Also

VERY IMPORTANT

, add your .env.development file to your .gitignore file. If you don't have one, create on in the root directory. This will prevent anyone looking at your code from seeing those values.

One last thing, install the dotenv package

npm install dotenv

Then require it on the top of the gatsby.config file, like this:

require("dotenv").config({ path: `.env.${process.env.NODE_ENV}` })

Congrats! you have configured Contentful to your Gatsby project. We can now fetch the created blogs, let's work on that next.

Query Contentful Blogs


In the gatsby-node.js file, we'll query the blogs that are stored in Contentful by its slug and used that to dynamically create pages for each blogs. An example code can be seen below:

const path = require("path");

module.exports.createPages = async ({ graphql, actions }) => { const postTemplate = path.resolve("./src/templates/post.js"); const { createPage } = actions; const res = await graphql(` query { allContentfulBlogPost { edges { node { slug } } } } `)

res.data.allContentfulBlogPost.edges.forEach(({ node }) => { createPage({ component: postTemplate, path: `/blogs/${node.slug}`, context: { slug: node.slug } }) }) }

Let's break this code down. We want to create a reference of the path to a template of our blog, which we have not yet created, we will after this part. Then we want to query all the blogs that are in Contentful and grab its slug. This may look a bit different for you depending on how you named your model. You can confirm by opening up your Gatsby localhost with the endpoint "/___graphql" (3 underscores). You should be able to find the path from there that is very similar to the code above.

After you grabbed the result of the query, you then want to loop through each node and invoke the createPage function, more info about this function can be found in the Gatsby Creating & Modifying documentation. It takes 3 parameters, the component which will be rendered for the blog, the path to the blog, and the context, which is the data that the blog is able to accept.

Blog Template

We're going to need a structure for the blogs that are going to be rendered from Contentful. Just like how we defined it in the gatsby-node file, we're going to create a template folder in the src and in that template folder, we're going to create a file called post.js.

Let's also keep this very simple, we're going to import 2 things, React from "react" and graphql from "gatsby".

import * as React from "react"; import { graphql } from "gatsby";

We want to use the qraphql import to query to blogs by its slug. We can do this with the following code:

export const pageQuery = graphql` query($slug: String!) { contentfulBlogPost(slug: { eq: $slug }) { title body { raw } } } `

If you included other fields, feel free to add those as well. Now lets create the code to render the text fields

const Post = ({ data }) => { return ( <Layout> <h1>{ data.contentfulBlogPost.title }</h1> <p>{ data.contentfulBlogPost.body.raw }</p> </Layout> ) }

Congrats! That is all. You have rendered the blogs from your Contentful account. You can now create new blogs from Contentful and it will be updated to you Gatsby site.

Following


There will be one issue you may deal with and it is the data you get back from rendering the body of the blog. It will seem unreadable but there are documents to address it. This plugin on Contentful Rich Text will help you make it more readable and adjust the type of fonts in the blog. But all in all you have integrated Contentful into your Gatsby site and I wish you the best on continuously improving your site!