Turbocharge Your Gatsby Site with GraphCMS

Static site generators like Gatsby have surged in popularity recently, allowing developers to create lightning-fast websites with React while retaining the benefits of static HTML files. But Gatsby‘s true superpower is its vast plugin ecosystem and ability to pull data from any source.

In this guide, we‘ll walk through integrating Gatsby with GraphCMS, a headless CMS that enables you to define structured content models and consume the data via a flexible GraphQL API. GraphCMS is an excellent pairing with Gatsby, giving you a friendly interface for content management while allowing developers to query data in a format that fits seamlessly into Gatsby‘s data layer.

Whether you‘re building a personal blog, a company marketing site, or a high-powered web app, this potent combination can help you build for the web faster. Let‘s dive in!

Getting Started

Before we begin, you‘ll need:

  • Basic familiarity with Gatsby and React
  • A Gatsby site to work with (starting with the default starter is fine)
  • A free GraphCMS account

Got those ready? Great, let‘s set up GraphCMS.

Defining Your Content Model in GraphCMS

GraphCMS allows you to define your content models in a flexible way to fit your needs. In this example, we‘ll create a simple "Blog Post" model.

After creating a new project in GraphCMS, head to the "Schema" tab in the sidebar. Click "Create Model" and name it "Blog Post".

Next, add some fields to the model. Let‘s go with:

  • Title (single line text)
  • Slug (single line text)
  • Excerpt (multi line text)
  • Content (multi line text, markdown enabled)
  • Cover Image (asset, image)

Creating a new content model in GraphCMS

You can of course customize these to your liking and even link to other content models. The beauty of a headless CMS is that your content is decoupled from your presentation, so you have complete flexibility.

With the model defined, go ahead and create a few sample blog posts in the "Content" tab. Let‘s move on to configuring the API.

Configuring GraphCMS API Permissions

In order for Gatsby to query your GraphCMS data, you need to enable read access to the published content. In your project‘s settings, navigate to "API Access" and scroll down to "Public API Permissions".

Set all of the models you want exposed to "Read". For our example, we just need to enable read access for the "Blog Post" model.

Setting API permissions in GraphCMS

While you‘re in the API settings, scroll a bit further down and copy your "Content API" endpoint. You‘ll need this to configure the Gatsby plugin. It should look something like:

https://api-us-west-2.graphcms.com/v2/your-project-id/master

With the GraphCMS side taken care of, let‘s jump into Gatsby!

Pulling GraphCMS Data into Gatsby

Gatsby has a powerful plugin called gatsby-source-graphql that allows you to query data from a GraphQL API and bring it into Gatsby‘s data layer. Let‘s set it up.

First, install the plugin:

npm install gatsby-source-graphql

Then, add it to your gatsby-config.js:

module.exports = {
  plugins: [
    {
      resolve: ‘gatsby-source-graphql‘,
      options: {
        typeName: ‘GraphCMS‘,
        fieldName: ‘graphcms‘,
        url: ‘YOUR_GRAPHCMS_ENDPOINT‘,
      },
    },
  ],
}

Be sure to replace YOUR_GRAPHCMS_ENDPOINT with the API URL you copied from GraphCMS in the previous step.

The typeName option determines how you‘ll refer to this data source in your GraphQL queries (in this case GraphCMS). The fieldName option will be the name of the root query field for this data source (graphcms).

With the plugin configured, restart your development server with gatsby develop. GraphCMS data is now available in Gatsby‘s data layer. Time to query it!

Querying GraphCMS Data in GraphiQL

Gatsby ships with a built-in GraphQL IDE called GraphiQL (pronounced "graphical"). It provides an interactive environment to explore your data and craft queries. Access it by navigating to http://localhost:8000/___graphql while your Gatsby development server is running.

In the GraphiQL Explorer pane on the left, you should see your GraphCMS data source listed as graphcms. Expand it and you‘ll see the available query fields based on your GraphCMS schema. For our "Blog Post" model, it should look something like:

{
  graphcms {
    blogPosts {
      title
      slug
      excerpt
      content
      coverImage {
        url
      }
    }
  }  
}

Click the "Play" button to execute the query and see the result in the response pane on the right. GraphiQL is a great way to test queries before adding them to your Gatsby pages and components.

Displaying GraphCMS Data in Pages & Components

Now for the fun part – displaying your GraphCMS data in your Gatsby site!

Gatsby uses a mesh of plugins, GraphQL queries, and React components to build pages. The GraphQL query tells Gatsby what data the page or component needs, then that data is passed into the React component as props to be rendered into HTML.

Let‘s build an index page that lists our blog posts. In src/pages/index.js:

import React from ‘react‘
import { graphql, Link } from ‘gatsby‘

const IndexPage = ({ data }) => {
  const { blogPosts } = data.graphcms
  return (
    <div>
      <h1>Blog Posts</h1>
      {blogPosts.map(post => (
        <div key={post.slug}>
          <img src={post.coverImage.url} alt={post.title} />
          <h2>
            <Link to={`/${post.slug}`}>{post.title}</Link>  
          </h2>
          <p>{post.excerpt}</p>
        </div>
      ))}
    </div>
  )
}

export const query = graphql`
  {
    graphcms {
      blogPosts {
        title
        slug
        excerpt
        coverImage {
          url
        }
      }
    }
  }
`

export default IndexPage

The graphql tagged template literal contains our GraphQL query that fetches the list of blog posts with the fields we want to display. This query is executed at build time and the result is passed into the IndexPage component as the data prop.

We destructure the blogPosts array from data.graphcms, then use map() to loop through the posts and render each one‘s cover image, title (wrapped in a link to the post‘s individual page), and excerpt.

To generate pages for each individual blog post, we can use Gatsby‘s createPages Node API in gatsby-node.js:

const path = require(‘path‘)

exports.createPages = async ({ actions: { createPage }, graphql }) => {
  const results = await graphql(`
    {
      graphcms {
        blogPosts {
          slug
        }
      }
    }
  `)

  results.data.graphcms.blogPosts.forEach(post => {
    createPage({
      path: `/${post.slug}`,
      component: path.resolve(‘./src/templates/blog-post.js‘),
      context: {
        slug: post.slug,
      },
    })
  })
}

This queries GraphCMS for just the slug field of each blog post, then loops through the results and uses createPage to dynamically generate a page for each post at its slug URL. It uses a page template component (blog-post.js) and passes the slug into the page query as variables.

Here‘s what the blog-post.js template might look like:

import React from ‘react‘
import { graphql } from ‘gatsby‘

const BlogPostTemplate = ({ data }) => {
  const { blogPost } = data.graphcms
  return (
    <div>
      <img src={blogPost.coverImage.url} alt={blogPost.title} />  
      <h1>{blogPost.title}</h1>
      <div dangerouslySetInnerHTML={{ __html: blogPost.content.html }} />
    </div>
  )
}

export const query = graphql`
  query BlogPostQuery($slug: String!) {
    graphcms {
      blogPost(where: { slug: $slug }) {
        title
        content {
          html
        }
        coverImage {
          url
        }  
      }
    }
  }
`

export default BlogPostTemplate

The page query uses a query variable $slug (passed in from createPage in gatsby-node.js) to fetch just the GraphCMS blog post that matches that slug value. The blogPost object is destructured from data.graphcms and its fields are rendered into the page template.

Note the content field is queried as html. This is because GraphCMS provides a Markdown to HTML transformation out of the box. The rendered HTML is output using React‘s dangerouslySetInnerHTML.

And there you have it! A Gatsby site pulling blog post content from GraphCMS. Of course, this just scratches the surface of what‘s possible with Gatsby and GraphCMS. You can create more complex content models, query relationships between models, filter and sort your content, generate category and tag pages, and so much more.

Tips & Best Practices

As you build out your Gatsby + GraphCMS site, here are a few tips to keep in mind:

  • Use clear, descriptive names for your GraphCMS models and fields. This will make your GraphQL queries more readable and maintainable.
  • Take advantage of GraphCMS‘s built-in rich text fields and transformations to easily render formatted content.
  • Use Gatsby‘s createPages API to dynamically generate pages from your GraphCMS content, whether that‘s blog posts, product pages, or something else.
  • Keep your GraphQL queries concise by only requesting the fields you need for that particular page or component. This helps avoid overfetching data and keeps your site lean.
  • Use GraphQL fragments to share query logic across multiple queries and components.
  • Structure your Gatsby project with a clear separation of concerns. Put GraphQL queries in their associated pages or components, use page templates, and keep your gatsby-node.js file clean and focused on page generation.

Gatsby + GraphCMS in the Wild

Wondering what kinds of sites are being built with Gatsby and GraphCMS? Here are a few real-world examples to inspire you:

  • Studious: A coding education platform using GraphCMS to manage their curriculum content.
  • StabPay: A fintech startup using Gatsby + GraphCMS for their marketing site, leveraging GraphCMS‘s localization features to serve content in multiple languages.
  • The Rick and Morty Wiki: A fan-made wiki site for the show "Rick and Morty," built with Gatsby and pulling character and episode data from GraphCMS.

The possibilities are endless! Whether you‘re building a personal blog, a corporate site, or a complex web app, Gatsby and GraphCMS provide a highly performant and flexible stack.

Wrapping Up

In this guide, we‘ve walked through the process of integrating GraphCMS content into a Gatsby site, from defining content models to querying data to generating pages. The combination of Gatsby‘s fast, React-based architecture and GraphCMS‘s flexible content management capabilities make them a powerful duo for building modern websites.

But don‘t just take my word for it – dive in and try it yourself! Experiment with different content models, build out more pages and components, and see how Gatsby and GraphCMS can streamline your web development workflow.

Happy coding!

Similar Posts