Learn how to build a Gatsby blog using [ButterCMS](https://buttercms.com/). 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](https://www.gatsbyjs.org/) 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](https://buttercms.com/blog/buttercms-vs-wordpress-headless-cms-vs-traditional-cms) offers a read-only API, that can be read by your static site generator. Gatsby combines React, [GraphQL](https://graphql.org/), webpack and other front-end technologies to provide a great developer experience. It’s a great choice if you are already familiar with [React](https://reactjs.org/) 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](https://buttercms.com/). 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 run `gatsby develop`, Gatsby will start a hot-reloading server at `[http://localhost:8000/](http://localhost:8000/.)`[.](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-defaultcd gatsby-sitegatsby develop ### Posts When building with Gatsby, you access your data via the query language [GraphQL](https://graphql.org/). 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](https://www.gatsbyjs.org/packages/gatsby-source-buttercms/?=buttercms) you can install. npm install --save gatsby-source-buttercms Add the plugin to your `gatsby-config.js` and 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, at `http://localhost:8000/___graphql` and explore the `butterPost` and`allButterPost` fields. { allButterPost { edges { node { title body } } }} The plugin maps all JSON fields documented in the [Butter CMS API Reference](https://buttercms.com/docs/api/#blog-engine) 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={`/${node.slug}`}>{node.title}</Link> }) return <Layout>{posts}</Layout>}export default BlogPageexport const pageQuery = graphql` query { allButterPost { edges { node { id slug title } } } } The page is now available at `/blog`. You can also edit the existing `src/pages/index.js` if 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 at `src/template/post.js`. You’ll then edit `gatsby-node.js` in your project’s root folder and use [Gatsby's Node APIs](https://www.gatsbyjs.org/docs/node-apis/), specifically the [createPages API](https://www.gatsbyjs.org/docs/node-apis/#createPages) and its [createPage action](https://www.gatsbyjs.org/docs/actions/#createPage). `**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 the `filter` argument 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 your `gatsby-config.js` and follow the same steps as for your blog posts, using the `butterPage` and `allButterPage` GraphQL fields. ButterCMS automatically generates a slug when you create a new page: A page titled `Example Page` gets an `example-page` slug, 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 add 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 the `limit` and `skip` arguments of the `allButterPost` and `allButterPage` fields in GraphQL. If you need help after reading this, contact ButterCMS’s support via [email](mailto:support@buttercms.com) or livechat. The [Gatsby Source Plugin for ButterCMS](https://www.gatsbyjs.org/packages/gatsby-source-buttercms/?=buttercms) is an open-source community plugin for Gatsby. If you want to contribute to the source plugin, open a [GitHub pull request](https://github.com/ButterCMS/gatsby-source-buttercms). If you have found a bug, open a [GitHub issue](https://github.com/ButterCMS/gatsby-source-buttercms). _If you’ve enjoyed this article, please help it spread by clapping below! For more content like this, follow us on_ [_Twitter_](https://twitter.com/ButterCMS) _and_ [_subscribe_](https://buttercms.com/blog/) _to our blog._ _And if you want to add a blog or CMS to your website without messing around with Wordpress,_ [_you should try Butter CMS_](https://buttercms.com/)_._ [ButterCMS](https://buttercms.com/) is a headless CMS that lets you build CMS-powered apps using any programming language including [Ruby](https://buttercms.com/ruby-cms/ "Ruby CMS"), [Rails](https://buttercms.com/rails-cms/ "Rails CMS"), [Node.js](https://buttercms.com/nodejs-cms/ "Node.js CMS"), [Python](https://buttercms.com/python-cms/ "Python CMS"), [ASP.NET](https://buttercms.com/asp-net-cms/ "ASP.NET CMS"), [Flask](https://buttercms.com/flask-cms/ "Flask CMS"), [Django](https://buttercms.com/django-cms/ "Django CMS"), [Go](https://buttercms.com/golang-cms/ "Golang CMS"), [PHP](https://buttercms.com/php-cms/ "PHP CMS API"), [Laravel](https://buttercms.com/laravel-cms/ "Laravel CMS"), [Angular](https://buttercms.com/angular-cms/ "Angular CMS API"), [React](https://buttercms.com/react-cms/ "React CMS API"), [Elixir](https://buttercms.com/elixir-cms/ "Elixir CMS"), [Phoenix](https://buttercms.com/phoenix-cms/ "Phoenix CMS"), [Meteor](https://buttercms.com/meteor-cms/ "Meteor CMS"), [Vue.js](https://buttercms.com/vuejs-cms/ "Vue.js CMS"), and [Gatsby.js](https://buttercms.com/gatsbyjs-cms/ "Gatsby.js CMS")