How to Integrate Netlify with Your Headless CMS
Connect Netlify to structured content so every publish can trigger a fresh build, preview, or deploy without copying content between tools.
What is Netlify?
Netlify is a web development platform for building, deploying, and hosting sites and web apps from Git-based workflows. Teams use it for static sites, Jamstack apps, serverless functions, edge logic, deploy previews, branch deploys, and form handling. It’s widely used by frontend teams working with frameworks like Next.js, Astro, Gatsby, Remix, Nuxt, and Eleventy.
Why integrate Netlify with a headless CMS?
If your site runs on Netlify but your content lives somewhere else, your build pipeline needs a reliable way to know when something changed. Without an integration, editors publish a page, developers manually trigger a deploy, someone waits for the build, and stale content can sit live for hours. That gets messy fast when you have multiple locales, product pages, author profiles, release notes, and campaign landing pages changing every day.
A headless CMS integration solves that by turning content events into Netlify actions. When an editor publishes, updates, or deletes content, a webhook can call a Netlify Build Hook or the Netlify API to start a new site build. With Sanity, structured content in the Content Lake means your frontend can fetch typed JSON during the build, not parse HTML or page blobs. GROQ lets the build request exactly the fields it needs, such as title, slug, hero image, author name, related products, and locale.
There are trade-offs. Triggering a full Netlify build on every small content update can waste build minutes on large sites. For high-change datasets, you’ll usually add filtering, batching, or selective rebuild patterns. Sanity webhooks and Functions help here because you can trigger Netlify only for specific document types, publish events, locales, or routes.
Architecture overview
A typical Sanity and Netlify integration starts when an editor publishes content in Sanity Studio. The mutation lands in the Content Lake as structured JSON. A Sanity webhook filters the event, for example only published `post`, `page`, or `product` documents, and sends the document ID and mutation type to a Netlify Function, an API route, or a Sanity Function. That server-side handler fetches the latest content from Sanity with GROQ. This is where you select only the fields Netlify’s build needs, such as `_id`, `_type`, `slug.current`, `title`, `language`, and referenced data like `author->name` or `category->slug.current`. The handler can then call Netlify in one of two common ways: `POST` to a Netlify Build Hook URL, or call the Netlify API with `createSiteBuild({ site_id })` using a Netlify personal access token. Netlify receives the build request, pulls the latest site code from Git, runs the configured build command, and your frontend fetches current Sanity content during build time or at request time, depending on your framework. The deployed result is served from Netlify’s hosting layer to visitors. For more advanced setups, Sanity Functions can run the server-side logic directly on content events, so you don’t need to host a separate webhook service.
Common use cases
Publish-triggered Netlify builds
Start a Netlify build the moment an editor publishes a page, post, product, or locale-specific document in Sanity.
Preview deploys for editorial review
Use Netlify deploy previews with Sanity draft content so editors can review real pages before publishing.
Multi-locale site rebuilds
Trigger Netlify only for affected language routes, such as `/en/pricing` or `/fr/tarifs`, when localized Sanity documents change.
Framework builds with structured data
Feed Astro, Gatsby, Next.js, Remix, or Nuxt builds on Netlify with typed JSON from Sanity’s Content Lake.
Step-by-step integration
- 1
Set up Netlify access
Create or choose a Netlify site, connect it to your Git repository, and confirm the build command and publish directory. In Netlify, create a personal access token from User settings, Applications, Personal access tokens. You can also create a Build Hook under Site configuration, Build & deploy, Continuous deployment, Build hooks if you prefer a URL-based trigger.
- 2
Install the packages
In the project that will receive Sanity webhooks, install the Netlify API client and Sanity client: `npm install netlify @sanity/client`. If you’re using a Netlify Function, also install `@netlify/functions` for TypeScript types.
- 3
Model the content in Sanity Studio
Define schema fields your Netlify frontend can build from, such as `title`, `slug`, `seoTitle`, `description`, `heroImage`, `body`, `language`, and references like `author` or `category`. Keep route fields predictable. A `slug.current` value is easier to map to Netlify routes than a freeform URL string.
- 4
Create the webhook or Function
Create a Sanity webhook that fires on create, update, delete, or publish mutations for the document types your site uses. Send it to a Netlify Function endpoint, such as `https://your-site.netlify.app/.netlify/functions/sanity-publish`, or use a Sanity Function if you want the event handling to live inside Sanity.
- 5
Call Netlify from the handler
In the handler, verify the request, fetch the latest document with GROQ, decide whether the change should trigger a build, and call Netlify’s API with `createSiteBuild({ site_id })`. For large sites, add guards so typo fixes to internal-only documents don’t start a full rebuild.
- 6
Test the full path
Publish a test document in Sanity Studio, confirm the webhook delivery, check the Netlify deploy log, and verify the rendered page. Test update and delete cases too. Deleted content often needs route cleanup, redirects, or a 404 path check.
Code example
import type { Handler } from "@netlify/functions";
import NetlifyAPI from "netlify";
import { createClient } from "@sanity/client";
const sanity = createClient({
projectId: process.env.SANITY_PROJECT_ID!,
dataset: process.env.SANITY_DATASET!,
apiVersion: "2025-01-01",
useCdn: false,
token: process.env.SANITY_READ_TOKEN
});
const netlify = new NetlifyAPI(process.env.NETLIFY_AUTH_TOKEN!);
export const handler: Handler = async (event) => {
const payload = JSON.parse(event.body || "{}");
const id = payload._id?.replace(/^drafts\./, "");
const doc = await sanity.fetch(
`*[_id == $id][0]{_id, _type, title, "slug": slug.current}`,
{ id }
);
if (!doc || !["page", "post", "product"].includes(doc._type)) {
return { statusCode: 202, body: "No Netlify build needed" };
}
await netlify.createSiteBuild({
site_id: process.env.NETLIFY_SITE_ID!
});
return {
statusCode: 200,
body: JSON.stringify({ queued: true, slug: doc.slug })
};
};How Sanity + Netlify works
Build your Netlify integration on Sanity
Sanity gives you the structured content foundation, real-time event system, and flexible APIs to connect Netlify builds, previews, and deploys to your publishing workflow.
Start building free →CMS approaches to Netlify
| Capability | Traditional CMS | Sanity |
|---|---|---|
| Content shape for Netlify builds | Often outputs rendered pages or mixed HTML, which makes static builds harder to map to clean routes and components. | Uses schema-as-code and structured JSON in the Content Lake, so routes, components, and fields stay explicit. |
| Triggering Netlify deploys | May need plugins, scheduled jobs, or manual deploy buttons to refresh the hosted site. | Uses GROQ-powered webhooks and Functions to trigger Netlify only for the content changes that matter. |
| Preview workflows | Preview is usually tied to the system’s own rendering layer, which can drift from the Netlify frontend. | Sanity Studio, Presentation Tool, and Netlify deploy previews can show editors draft content in the real frontend. |
| Query control during builds | Builds may need to fetch full pages or broad API responses, then filter data in application code. | GROQ can filter, project, join references, sort, and slice content in one query for faster Netlify builds. |
| Handling large sites | Full rebuilds are common, and fine-grained invalidation can be hard to set up. | Webhook filters, Functions, and Sync tags help you route changes to the right Netlify build, cache update, or frontend path. |
| Beyond the website | Content is often page-first, so reuse in apps, agents, and external systems takes cleanup. | The same structured back end can power Netlify, mobile apps, search, Agent Context, and AI content workflows. |
Keep building
Explore related integrations to complete your content stack.
Sanity + Next.js
Build dynamic and static Next.js sites with structured Sanity content, draft previews, and route-aware rendering.
Sanity + Astro
Ship fast Astro sites on Netlify while pulling typed content from Sanity at build time.
Sanity + Gatsby
Use Sanity content in Gatsby builds with predictable routes, previews, and publish-triggered deploys.