How to Build a Blog with Gatsby and Contentful

In this tutorial, we will explore how to build a blog using Gatsby and Contentful. Gatsby is a popular static site generator built with React, and Contentful is a headless content management system (CMS). Combining these two technologies allows you to create a dynamic blog with a smooth development experience.

Prerequisites

Before we get started, make sure you have the following installed on your machine:

  • Node.js (v12 or higher)
  • npm (v6 or higher)

Step 1: Set up a Gatsby project

To begin, let’s create a new Gatsby project by opening a terminal and running the following command:

npx gatsby new gatsby-blog

This will create a new Gatsby project called “gatsby-blog” in a directory of the same name. Go into the project directory:

cd gatsby-blog

Step 2: Install required dependencies

Next, we need to install the necessary packages for our blog. Run the following command to install the required dependencies:

npm install gatsby-source-contentful contentful gatsby-transformer-remark react-helmet
  • gatsby-source-contentful is a Gatsby plugin that allows us to pull data from Contentful into our Gatsby website.
  • contentful is the official Contentful JavaScript SDK.
  • gatsby-transformer-remark is a plugin for transforming Markdown files into HTML.
  • react-helmet allows us to manipulate the head of our HTML document.

Step 3: Configure Contentful

To connect our Gatsby project with Contentful, we need to set up a Contentful account and create a new space.

  1. Go to the Contentful website and sign up for a new account if you don’t already have one.
  2. Once logged in, click on the “Create space” button to create a new space.
  3. Give your space a name (e.g., “Gatsby Blog”) and select the option “Website” for the purpose of your space.
  4. After creating the space, you’ll be directed to the Contentful web app.

Keep this browser tab open as we’ll need the information from this page later.

Step 4: Create a Contentful content model

In Contentful, a content model defines the structure of the content in each entry. We need to create a content model for our blog posts.

  1. In the Contentful web app, click on the “Content model” option on the left sidebar.
  2. Click on the “+ Add Content Type” button and name it “Blog Post”.
  3. Add the following fields to the “Blog Post” content type:
  • Title (Text field)
  • Slug (Symbol field)
  • Published date (Date & time field)
  • Body (Rich text field)
  • Cover image (Media field)
  1. Once you have added all the fields, click on the “Save” button to save the content model.

Step 5: Retrieve Contentful API keys

In order for our Gatsby project to access the content from Contentful, we need to retrieve our Contentful API keys.

  1. In the Contentful web app, go to “Settings” in the top-right corner.
  2. Under the “API keys” tab, click on the “Add API key” button.
  3. Give your API key a name (e.g., “Gatsby Blog API key”) and select the “Content Delivery” role.
  4. After creating the API key, you will see two keys: “Space ID” and “Content Delivery API – access token”.

Make sure to keep these API keys safe and avoid sharing them publicly.

Step 6: Configure Gatsby to use the Contentful plugin

To connect our Gatsby project with Contentful, we need to configure the gatsby-config.js file.

  1. Open the gatsby-config.js file in the root of your project.
  2. Replace the existing plugins array with the following code:
module.exports = {
  siteMetadata: {
    title: "Gatsby Blog",
  },
  plugins: [
    {
      resolve: `gatsby-source-contentful`,
      options: {
        spaceId: process.env.CONTENTFUL_SPACE_ID,
        accessToken: process.env.CONTENTFUL_ACCESS_TOKEN,
      },
    },
    `gatsby-transformer-remark`,
  ],
};

We are setting the spaceId and accessToken options for the gatsby-source-contentful plugin. However, instead of hardcoding these values, we will use environment variables in the next step.

Step 7: Set up environment variables

We need to set up environment variables to securely store our Contentful API keys.

  1. Create a new file called .env.development in the root of your project.
  2. Add the following content to the file:
CONTENTFUL_SPACE_ID=<your-contentful-space-id>
CONTENTFUL_ACCESS_TOKEN=<your-contentful-access-token>

Replace <your-contentful-space-id> and <your-contentful-access-token> with the corresponding values from step 5.

  1. Create a similar .env.production file and fill in the same values.

Step 8: Create a blog post template

To display the blog posts on our Gatsby blog, we need to create a template.

  1. Create a new directory called src/templates in the root of your project.
  2. Inside the templates directory, create a new file called blog-post.js.
  3. Add the following content to the blog-post.js file:
import React from "react";
import { graphql } from "gatsby";
import { Helmet } from "react-helmet";

export default function BlogPost({ data }) {
  const post = data.contentfulBlogPost;

  return (
    <div>
      <Helmet>
        <title>{post.title} - Gatsby Blog</title>
      </Helmet>
      <h1>{post.title}</h1>
      {post.publishedDate}
      <div
        dangerouslySetInnerHTML={{ __html: post.body.childMarkdownRemark.html }}
      />
    </div>
  );
}

export const query = graphql`
  query($slug: String!) {
    contentfulBlogPost(slug: { eq: $slug }) {
      title
      publishedDate(formatString: "MMMM Do, YYYY")
      body {
        childMarkdownRemark {
          html
        }
      }
    }
  }
`;

The BlogPost component receives the data prop, which contains the blog post data from Contentful. We are using the Helmet component from react-helmet to set the page title dynamically based on the blog post.

The GraphQL query at the bottom fetches the blog post data for the specified slug.

Step 9: Fetch and render blog posts

Now let’s fetch the blog posts from Contentful and render them on our Gatsby blog.

  1. Open the gatsby-node.js file in the root of your project.
  2. Replace the existing code with the following:
exports.createPages = async ({ graphql, actions }) => {
  const { createPage } = actions;
  const result = await graphql(`
    query {
      allContentfulBlogPost {
        edges {
          node {
            slug
          }
        }
      }
    }
  `);

  result.data.allContentfulBlogPost.edges.forEach(({ node }) => {
    createPage({
      path: `/blog/${node.slug}`,
      component: require.resolve("./src/templates/blog-post.js"),
      context: {
        slug: node.slug,
      },
    });
  });
};

We are using the createPages API from Gatsby’s Node API to dynamically create pages for each blog post. The createPage function creates a new page at the specified path, uses the blog-post.js template we created earlier, and passes the blog post slug as a context.

Step 10: Style the blog

The last step before launching our blog is to add some styling.

  1. Open the src/components/layout.css file.
  2. Replace the existing content with the following CSS:
body {
  margin: 0;
  padding: 0;
  font-family: Arial, sans-serif;
}

h1 {
  margin-bottom: 0.5rem;
}

p {
  color: #888;
  margin-top: 0;
}

a {
  color: #007bff;
  text-decoration: none;
}

.blog-post {
  max-width: 800px;
  margin: 2rem auto;
}

This CSS will give the blog posts a simple and clean styling.

Step 11: Start the development server

Finally, let’s start our Gatsby development server and see the blog in action.

Run the following command in the terminal:

npm run develop

Your blog should now be accessible at `http://localhost:8000`.

Conclusion

In this tutorial, we learned how to build a blog using Gatsby and Contentful. We set up a Gatsby project, connected it with Contentful, created a content model for blog posts, and fetched and rendered the posts. With this foundation, you can extend your blog with features like pagination, comments, and search. Happy blogging!

Related Post