Frameworks & Hosting8 min read

How to Integrate Gatsby with Your Headless CMS

Connect Gatsby to structured content so every publish can rebuild the right pages, refresh previews, and ship fast static experiences without copying JSON by hand.

Published April 29, 2026
01Overview

What is Gatsby?

Gatsby is an open-source React framework for building static sites, Deferred Static Generation pages, and server-rendered routes. It has a GraphQL data layer, an image pipeline, and a plugin system that teams use for marketing sites, documentation, ecommerce frontends, and campaign pages. Gatsby is especially common when you want fast page loads, Git-based builds, and content pulled from external APIs at build time.


02The case for integration

Why integrate Gatsby with a headless CMS?

Gatsby works best when content is cleanly structured before the build starts. If your editors publish a product guide, case study, or landing page, Gatsby needs predictable fields like title, slug, heroImage, sections, author, and relatedLinks so it can create pages, generate images, and build its GraphQL schema without guesswork.

A headless CMS can provide that API layer, but the quality of the integration depends on how the content is modeled and how fast changes reach Gatsby. With Sanity's AI Content Operating System, content lives as typed JSON in the Content Lake. GROQ selects exactly the fields Gatsby needs, webhooks fire when content is published, updated, or deleted, and Functions can run server-side logic before a rebuild starts.

The alternative is usually slower and messier. Someone exports content to a file, pastes HTML into a repository, waits for a scheduled build, or writes one-off scripts that fetch too much data. That can work for a 12-page site. It gets painful when you have 1,000 product pages, localized routes, draft previews, and editors expecting changes to show up within minutes.


03Architecture

Architecture overview

A typical Gatsby integration starts in Sanity Studio, where editors publish structured documents such as posts, landing pages, products, and authors. Those documents are written to the Content Lake as typed JSON, including references between documents and assets. On publish, a Sanity webhook can trigger a Gatsby rebuild through your hosting provider's build hook, such as Netlify or Vercel. You can filter the webhook with GROQ so only relevant mutations trigger the build, for example posts, pages, or products with a defined slug. If you need extra logic, a Sanity Function can run on the content event, inspect the mutation, fetch related documents, and call the build hook without running a separate server. During the Gatsby build, Gatsby's Node APIs, such as sourceNodes and createPages, fetch content from Sanity with @sanity/client and GROQ. The query projects only what Gatsby needs, including joined references like author->name and category[]->slug.current. Gatsby turns that data into GraphQL nodes, creates routes from slugs, renders HTML, builds page-data JSON, and deploys the result to your CDN. End users get static pages, while editors get a publish flow that can trigger rebuilds automatically.


04Use cases

Common use cases

📝

Marketing site rebuilds on publish

Publish a landing page in Sanity Studio, trigger a Gatsby rebuild through a build hook, and ship the updated static route to your CDN.

📚

Documentation with structured navigation

Model docs, sidebars, release notes, and authors in Sanity, then let Gatsby generate section pages and nested routes from GROQ results.

🛍️

Product content for static storefronts

Use Gatsby for fast product detail pages while Sanity keeps product stories, buying guides, SEO fields, and merchandising copy structured.

🌎

Localized campaign pages

Query locale-specific titles, slugs, Portable Text, and metadata so Gatsby can build /en, /fr, and /de routes from one content model.


05Implementation

Step-by-step integration

  1. 1

    Create the Gatsby site and deployment target

    Start a Gatsby project with npm create gatsby@latest or add Sanity to an existing Gatsby site. Gatsby itself doesn't require an account or API key. Your hosting provider does, so create a Netlify or Vercel project, add a build hook URL, and save it as GATSBY_BUILD_HOOK_URL.

  2. 2

    Add Sanity credentials and client packages

    Install the packages Gatsby will use to read content: npm install @sanity/client. Add SANITY_PROJECT_ID, SANITY_DATASET, and SANITY_API_VERSION to your environment. Use a read token only if Gatsby needs to read drafts or private datasets.

  3. 3

    Model the content in Sanity Studio

    Create schemas that match Gatsby routes, not just editor screens. For a blog, define post fields like title, slug, excerpt, mainImage, author reference, categories references, body, seoTitle, seoDescription, and publishedAt.

  4. 4

    Source Sanity content into Gatsby

    Use Gatsby's sourceNodes API or gatsby-source-sanity. With sourceNodes, fetch documents using GROQ, create Gatsby nodes with createNode, and then use createPages to generate routes from each slug.

  5. 5

    Trigger builds from publish events

    Create a Sanity webhook that fires on create, update, and delete for route-building document types. Point it at a webhook handler, a Sanity Function, or directly at your hosting build hook. If you need to inspect the changed document first, fetch it with GROQ before calling the build hook.

  6. 6

    Test the full publish path

    Publish a test document, confirm the webhook fires, verify that the hosting build starts, and check that Gatsby creates the expected page. Also test delete and slug-change cases, because those are where stale static pages most often appear.


06Code

Code example

This example shows the practical flow: a webhook handler receives a Sanity publish event, fetches the changed document with GROQ, and triggers a Gatsby rebuild. During the build, Gatsby uses its Node API to pull Sanity content into Gatsby nodes.

typescript
import {createClient} from '@sanity/client'
import type {VercelRequest, VercelResponse} from '@vercel/node'
import type {GatsbyNode} from 'gatsby'

const sanity = createClient({
  projectId: process.env.SANITY_PROJECT_ID!,
  dataset: process.env.SANITY_DATASET!,
  apiVersion: '2025-01-01',
  useCdn: false,
})

export default async function handler(req: VercelRequest, res: VercelResponse) {
  if (req.method !== 'POST') return res.status(405).end()

  const doc = await sanity.fetch(
    '*[_id == $id][0]{_type,title,"slug":slug.current}',
    {id: req.body._id}
  )

  if (!doc?.slug) return res.status(202).json({skipped: true})

  await fetch(process.env.GATSBY_BUILD_HOOK_URL!, {method: 'POST'})
  return res.status(200).json({queued: true, doc})
}

export const sourceNodes: GatsbyNode['sourceNodes'] = async ({actions, createNodeId, createContentDigest}) => {
  const posts = await sanity.fetch(
    '*[_type == "post" && defined(slug.current)]{_id,title,"slug":slug.current,excerpt,"author":author->name}'
  )

  posts.forEach((post: any) => {
    actions.createNode({
      ...post,
      id: createNodeId(`sanity-post-${post._id}`),
      parent: null,
      children: [],
      internal: {type: 'SanityPost', contentDigest: createContentDigest(post)},
    })
  })
}

07Why Sanity

How Sanity + Gatsby works

Build your Gatsby integration on Sanity

Sanity gives you the structured content foundation, real-time event system, and flexible APIs to connect Gatsby builds to the content your team publishes.

Start building free →

08Comparison

CMS approaches to Gatsby

CapabilityTraditional CMSSanity
Gatsby data shapeOften exposes rendered pages or plugin-specific exports, which can require HTML cleanup before Gatsby can build typed nodes.Returns typed JSON from the Content Lake, with GROQ projections that match the exact Gatsby node shape you want.
Publish-to-build flowMay rely on manual rebuilds, scheduled jobs, or plugins that are tied to one hosting setup.Uses GROQ-filtered webhooks and Functions so only relevant content changes call your Gatsby build hook.
Reference handlingRelationships are often page-centric, so Gatsby may need extra requests to connect authors, categories, and related content.GROQ can join references in one query, such as author->name and categories[]->slug.current, before Gatsby creates nodes.
Preview and draft contentPreview often works inside the original system, but matching Gatsby's production routes can take custom plugin work.Drafts can be queried with the right perspective and token, then used in Gatsby preview builds or a separate preview app.
Scale across channelsWorks well when the website is the main output, but mobile apps and AI agents may need separate content paths.Models your business as structured content, so Gatsby, mobile apps, commerce surfaces, and AI agents can read from one source.
Setup trade-offFast for simple brochure sites if editors are already trained in the system.Requires schema design in code, but that gives Gatsby predictable content shapes, version control, and editor interfaces built for your workflow.

09Next steps

Keep building

Explore related integrations to complete your content stack.

Ready to try Sanity?

See how Sanity's Content Operating System powers integrations with Gatsby and 200+ other tools.