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.
- Go to the Contentful website and sign up for a new account if you don’t already have one.
- Once logged in, click on the “Create space” button to create a new space.
- Give your space a name (e.g., “Gatsby Blog”) and select the option “Website” for the purpose of your space.
- 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.
- In the Contentful web app, click on the “Content model” option on the left sidebar.
- Click on the “+ Add Content Type” button and name it “Blog Post”.
- 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)
- 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.
- In the Contentful web app, go to “Settings” in the top-right corner.
- Under the “API keys” tab, click on the “Add API key” button.
- Give your API key a name (e.g., “Gatsby Blog API key”) and select the “Content Delivery” role.
- 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.
- Open the
gatsby-config.js
file in the root of your project. - 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.
- Create a new file called
.env.development
in the root of your project. - 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.
- 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.
- Create a new directory called
src/templates
in the root of your project. - Inside the
templates
directory, create a new file calledblog-post.js
. - 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.
- Open the
gatsby-node.js
file in the root of your project. - 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.
- Open the
src/components/layout.css
file. - 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!