Frameworks & Hosting8 min read

How to Integrate Next.js with Your Headless CMS

Connect Next.js to structured content so editors can publish once, trigger real-time revalidation, and ship updated pages without waiting for a full rebuild.

Published April 29, 2026
01 β€” Overview

What is Next.js?

Next.js is a React framework from Vercel for building web applications with file-based routing, server components, API routes, static generation, server rendering, and incremental static regeneration. It’s widely used by product teams, marketing teams, and commerce teams that need fast pages, flexible rendering, and hosting options across Vercel, Netlify, self-hosted Node.js, and edge runtimes.


02 β€” The case for integration

Why integrate Next.js with a headless CMS?

Next.js gives you several ways to render content: at build time, per request, on a schedule, or on demand. That flexibility is useful, but it also means your content source needs to tell Next.js exactly what changed. If every content edit requires a full site rebuild, a small typo fix can turn into a 10-minute wait on a large site.,A headless CMS integration solves that by giving Next.js structured content through APIs instead of page-shaped HTML blobs. With Sanity, content is typed JSON in the Content Lake, so your app can query only the fields it needs: title, slug, hero image, related products, author, and publish date. GROQ handles filters and joins across references, which keeps your Next.js data fetching code small and specific.,The alternative is usually a mix of manual rebuilds, copied content, hardcoded landing pages, and scripts that poll for changes every few minutes. That works for a five-page site. It breaks down when you have 2,000 product detail pages, three locales, scheduled launches, and editors who expect published changes to appear right away. Webhooks and Functions let Sanity notify Next.js on publish, update, or delete events, so you can revalidate only the affected routes or cache tags.


03 β€” Architecture

Architecture overview

A typical setup starts with editors working in Sanity Studio, where schemas define content such as posts, products, authors, landing pages, and navigation. When an editor publishes, the document is written to the Content Lake. A Sanity webhook can fire on that publish event and call a Next.js Route Handler, for example POST /api/revalidate. The handler reads the mutation payload, uses @sanity/client to run a GROQ query for the current document and any referenced fields Next.js needs, then calls Next.js revalidateTag() or revalidatePath() from next/cache. On the next request, Next.js fetches fresh content from Sanity and serves the updated page to the user. If you need server-side processing before calling Next.js, such as mapping changed product content to multiple route paths or sending a notification to another system, a Sanity Function can run that logic on the content event without a separate worker service.


04 β€” Use cases

Common use cases

πŸ“°

Editorial sites with ISR

Publish articles in Sanity Studio and trigger Next.js on-demand revalidation for only the changed article, author page, and section listing.

πŸ›’

Commerce product pages

Use structured product content, references, and localized fields from Sanity to render Next.js product detail pages without mixing copy into commerce inventory systems.

🎯

Campaign landing pages

Let marketers launch Next.js landing pages from reusable Sanity schemas while developers keep control of React components, routing, and deployment.

πŸ‘€

Preview and visual editing

Use draft mode, Presentation Tool, and Content Source Maps so editors can preview Next.js pages and click from rendered content back to the source field.


05 β€” Implementation

Step-by-step integration

  1. 1

    Create the Next.js app and add Sanity config

    Create an app with npx create-next-app@latest, then install the Sanity client with npm install @sanity/client. Add NEXT_PUBLIC_SANITY_PROJECT_ID, NEXT_PUBLIC_SANITY_DATASET, SANITY_API_READ_TOKEN, and SANITY_WEBHOOK_SECRET to .env.local. Keep read tokens server-side unless the dataset is public.

  2. 2

    Model content in Sanity Studio

    Define schemas for the content your routes need. For a blog, start with post fields such as title, slug, excerpt, mainImage, body, author reference, categories, publishedAt, and seo. For commerce, include productCopy, slug, gallery, specs, relatedProducts, and localized descriptions.

  3. 3

    Fetch Sanity content from Next.js

    Create a server-only Sanity client and use GROQ in React Server Components, generateStaticParams(), generateMetadata(), or Route Handlers. Tag cached fetches by content type and slug so they can be revalidated when Sanity sends a webhook.

  4. 4

    Create the publish sync mechanism

    Add a Next.js Route Handler at app/api/revalidate/route.ts. Configure a Sanity webhook to call that URL on create, update, publish, and delete events. Use a GROQ filter such as _type in ['post', 'page', 'product'] to avoid firing on documents Next.js doesn’t render.

  5. 5

    Call Next.js revalidation APIs

    Inside the route handler, verify the webhook secret, fetch the changed document with @sanity/client, and call revalidateTag() or revalidatePath(). Use tags for list pages, such as sanity:post, and slug-specific tags for detail routes, such as sanity:post:my-article.

  6. 6

    Test previews, publishing, and cache behavior

    Run next dev, publish a test document in Sanity Studio, and confirm that the webhook returns 200. Then test production behavior after deployment, since ISR, cache tags, and route revalidation can behave differently between local development and hosted environments.


06 β€” Code

Code example

typescriptapp/api/revalidate/route.ts
import {createClient} from '@sanity/client'
import {revalidateTag} from 'next/cache'
import {NextRequest, NextResponse} from 'next/server'

const client = createClient({
  projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID!,
  dataset: process.env.NEXT_PUBLIC_SANITY_DATASET!,
  apiVersion: '2025-01-01',
  token: process.env.SANITY_API_READ_TOKEN,
  useCdn: false,
})

export async function POST(req: NextRequest) {
  if (req.headers.get('x-sanity-secret') !== process.env.SANITY_WEBHOOK_SECRET) {
    return NextResponse.json({message: 'Invalid secret'}, {status: 401})
  }

  const {_id} = await req.json()
  const doc = await client.fetch(
    `*[_id == $id][0]{_id, _type, title, slug, "author": author->name}`,
    {id: _id}
  )

  if (!doc) return NextResponse.json({revalidated: false})

  revalidateTag(`sanity:${doc._type}`)
  if (doc.slug?.current) revalidateTag(`sanity:${doc._type}:${doc.slug.current}`)

  return NextResponse.json({revalidated: true, doc})
}

07 β€” Why Sanity

How Sanity + Next.js works

Build your Next.js integration on Sanity

Sanity gives you the structured content foundation, real-time event system, GROQ queries, and flexible APIs to connect Next.js to the AI Content Operating System.

Start building free β†’

08 β€” Comparison

CMS approaches to Next.js

CapabilityTraditional CMSSanity
Rendering strategy fitOften serves finished pages, so Next.js may need scraping, embedded HTML, or custom export scripts.Provides structured JSON from the Content Lake, so Next.js can render with SSG, ISR, SSR, React Server Components, or Route Handlers.
Publish-to-cache flowCommonly relies on full rebuilds, scheduled exports, or manual cache clears.Uses webhooks or Functions to trigger Next.js revalidateTag() or revalidatePath() when specific content changes.
Field-level query controlAPIs may return page HTML or large payloads that include fields the route doesn’t need.GROQ selects exact fields, filters drafts or published content, and joins references in one query for a Next.js route.
Preview and editor feedbackPreview often happens inside the publishing tool, not against the actual Next.js app.Draft mode, Presentation Tool, and Content Source Maps connect rendered Next.js elements back to Sanity Studio fields.
Schema changesContent structures may be configured in an admin UI, which can make code review and version history harder.Schema-as-code keeps content models in version control with the Next.js codebase, which helps teams review changes before release.
AI agent readinessContent may be page-shaped, which means agents need extra extraction or cleanup before answering questions.Agent Context gives production AI agents scoped, read-only access to schema-aware content from the same source Next.js uses.

09 β€” Next 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 Next.js and 200+ other tools.