GSD
How to Use Gatsby with a Headless CMS
Posted by Manuel Wieser on September 21, 2023
Learn how to build a Gatsby blog using ButterCMS. The code examples in this article let you combine Gatsby and ButterCMS in just a few minutes, no matter if you are a beginner or an expert.
Why Gatsby and ButterCMS?
Gatsby is a static site generator based on React and GraphQL. ButterCMS is a headless CMS and blogging platform. What does that mean and why should you use them?
A static site (HTML, CSS, and JavaScript) is fast, secure and flexible. There is no database or server-side code that attackers can exploit. A static site generator pulls data from APIs, databases or files and generates pages using templates.
As a developer, you probably want to write your content as Markdown files. However, if your static site's content has to be managed by non-developers, they'll prefer a CMS. A headless CMS offers a read-only API, that can be read by your static site generator. (Learn more about the benefits of a headless CMS and why more WordPress users are using it as a headless option)
Gatsby combines React, GraphQL, webpack and other front-end technologies to provide a great developer experience. It's a great choice if you are already familiar with React and JSX. ButterCMS allows you to add a CMS to your Gatsby sites without having to worry about hosting, security, or performance. You can focus on implementing your front-end.
Now that we know the benefits of Gatsby and ButterCMS, let's get started!
Setup
First, create a ButterCMS account. You'll be provided with an API token and an example blog post. You'll need both for this tutorial.
Next, install the Gatsby CLI.
npm install --global gatsby-cli
You can then create a new site from the official starting template. If you navigate to the directory and gatsby develop
Gatsby will start a hot-reloading server http://localhost:8000/
This way, you don’t have to refresh your page as Gatsby injects new versions of the files that you edited at runtime.
gatsby new gatsby-site https://github.com/gatsbyjs/gatsby-starter-default
cd gatsby-site
gatsby develop
Posts
When building with Gatsby, you access your data via the query language GraphQL. There are many official and community plugins that fetch data from remote or local locations and make it available via GraphQL. These plugins are called "source plugins" and there is already a Gatsby Source Plugin for ButterCMS you can install.
npm install --save gatsby-source-buttercms
Add the plugin to gatsby-config.js
copy and paste your ButterCMS API token.
module.exports = {
plugins: [
{
resolve: 'gatsby-source-buttercms',
options: {
authToken: 'your_api_token'
}
}
]
}
After this change, you might have to restart the hot-reloading server (gatsby develop
) before you can test the GraphQL fields and types the plugin is providing.
Head to GraphiQL, the in-browser IDE for exploring GraphQL, http://localhost:8000/___graphql
explore butterPost
allButterPost
.
{
allButterPost {
edges {
node {
title
body
}
}
}
}
The plugin maps all JSON fields documented in the Butter CMS API Reference to GraphQL fields.
Add a list of your blog posts
Your ButterCMS data can now be queried in any Gatsby page or template. You can start by creating a src/pages/blog.js
and adding a list of your blog posts.
import React from 'react'
import { graphql, Link } from 'gatsby'
import Layout from '../components/layout'
const BlogPage = ({ data }) => {
const posts = data.allButterPost.edges
.map(({ node }) => {
return <Link key={node.id} to={`/blog/${node.slug}`}>{node.title}</Link>
})
return <Layout>{posts}</Layout>
}
export default BlogPage
export const pageQuery = graphql`
query {
allButterPost {
edges {
node {
id
slug
title
}
}
}
}
The page is now available /blog
You can also edit the src/pages/index.js
you want to have the list on your home page.
Add pages for your blog posts
Generating a page for each of your posts requires you to create a template src/template/post.js
You’ll then gatsby-node.js
your project’s root folder and use Gatsby's Node APIs, specifically the createPages API and its createPage action.
src/templates/post.js
import React from 'react'
import { graphql } from 'gatsby'
import Layout from '../components/layout'
export default function Template({ data }) {
const { title, date, body } = data.butterPost
return (
<Layout>
<h1>{title}</h1>
<h2>{date}</h2>
<div dangerouslySetInnerHTML={{ __html: body }} />
</Layout>
)
}
export const pageQuery = graphql`
query($slug: String!) {
butterPost(slug: { eq: $slug }) {
title
date
body
}
}
`
gatsby-node.js
const path = require('path')
exports.createPages = ({ actions, graphql }) => {
const { createPage } = actions
const template = path.resolve(`src/templates/post.js`)
return graphql(`
{
allButterPost {
edges {
node {
slug
}
}
}
}
`).then(result => {
if (result.errors) {
return Promise.reject(result.errors)
}
result.data.allButterPost.edges.forEach(({ node }) => {
console.log(node);
createPage({
path: `/blog/${node.slug}`,
component: template,
context: {
slug: node.slug
}
})
})
})
}
Categories, Tags, and Authors
Use filter
against your ButterCMS categories, tags, and authors to feature and filter the content of your blog.
{
allButterPost(filter: {
tags: {
elemMatch: {
slug: { in: "example-tag" }
}
}
}) {
edges {
node {
id
title
}
}
}
}
Pages
If you want to add ButterCMS pages to your blog, add a list of page slugs to gatsby-config.js
follow the same steps as for your blog posts, using butterPage
allButterPage
GraphQL fields.
ButterCMS automatically generates a slug when you create a new page: A page Example Page
example-page
, which is shown below the page title in the ButterCMS editor. You can add these slugs to your gatsby-config.js
:
module.exports = {
plugins: [
{
resolve: 'gatsby-source-buttercms',
options: {
authToken: 'your_api_token',
pages: [
'homepage'
]
}
}
]
}
{
allButterPage(filter: {slug: {eq: "homepage"}}) {
edges {
node {
slug
}
}
}
}
You can also specify a page type in your gatsby-config.js
:
module.exports = {
plugins: [
{
resolve: 'gatsby-source-buttercms',
options: {
authToken: 'your_api_token',
pageTypes: [
'products'
]
}
}
]
}
To get all pages for a given type you can then use the following GraphQL query:
{
allButterPage(filter: {page_type: {eq: "products"}}) {
edges {
node {
slug
}
}
}
}
Conclusion
We have learned how to use a Gatsby source plugin to convert headless CMS data to Gatsby nodes, how to query those nodes with GraphQL, and how to create pages. This should give you a head start when building a Gatsby blog with ButterCMS.
Where to go from here? You could use what you’ve learned and a page that lists your categories and tags. If you already have a lot of content, you might want to add pagination to your list of blog posts.
You can do so by using limit
skip
of allButterPost
allButterPage
in GraphQL.
If you need help after reading this, contact ButterCMS’s support via email or .
The Gatsby Source Plugin for ButterCMS is an open-source community plugin for Gatsby. If you want to contribute to the source plugin, open a GitHub pull request. If you have found a bug, open a GitHub issue.
ButterCMS is the #1 rated Headless CMS
Related articles
Don’t miss a single post
Get our latest articles, stay updated!
Manuel is Lead Web Developer at karriere.at, lecturer at the University of Applied Sciences Upper Austria and writes about Front-End Development, Games and Digital Art on his personal blog manu.ninja.