Sanity + Next.js Integration

Modern headless CMS integration for dynamic content delivery. Connect Sanity's real-time content platform with Next.js's flexible rendering strategies.

Why Sanity + Next.js?

The combination of Sanity and Next.js represents a modern approach to content-driven websites and applications. Sanity's real-time content platform pairs seamlessly with Next.js's flexible rendering strategies, enabling developers to build sites that balance performance with editorial flexibility.

This integration leverages Sanity's structured content model and GROQ query language alongside Next.js's server components, static generation, and edge capabilities. The result is a development experience where content editors work in a customizable Studio environment while developers benefit from type-safe content access and modern React patterns.

The synergy between Sanity's content lake and Next.js's rendering modes creates a powerful workflow. Real-time collaboration allows multiple team members to work simultaneously on content, with live updates visible across the platform. Instant previews mean editors can see changes immediately without waiting for builds, and content updates propagate immediately without requiring new deployments.

For teams building AI-powered applications, this integration provides the structured content foundation needed for intelligent content delivery and personalization at scale.

Core Integration Benefits

Type Safety and Developer Experience: Sanity generates TypeScript types from schemas, providing compile-time safety for content access. Combined with Next.js's type-safe server components, this creates a robust development workflow where content structure changes are caught early.

Flexible Rendering Strategies: Next.js supports multiple rendering approaches--Static Site Generation (SSG), Incremental Static Regeneration (ISR), Server-Side Rendering (SSR), and Client-Side Rendering. Sanity integrates with all these patterns, allowing developers to choose the optimal strategy for each page or component.

Real-Time Collaboration: Sanity's real-time editing capabilities mean multiple team members can work simultaneously, with live updates visible across the platform. Next.js preview modes connect directly to this real-time engine.

For comprehensive integration patterns and best practices, refer to Sanity's official Next.js exchange.

Integration Capabilities

Key features that make Sanity + Next.js a powerful combination

Type-Safe Content

Generate TypeScript types from Sanity schemas for compile-time content validation and IDE autocomplete.

Flexible Rendering

Use SSG, ISR, SSR, or client-side rendering based on content needs and performance requirements.

Visual Editing

Enable editors to modify content directly in the live page context through Sanity's Presentation tool.

Real-Time Preview

See draft content and live updates instantly as editors work in Sanity Studio.

Client Setup

Setting up the Sanity client in a Next.js project involves installing the official packages, configuring environment variables, and creating a type-safe client instance. This foundation enables all subsequent operations, from content fetching to live preview.

Installation and Dependencies

The primary package for Sanity + Next.js integration is next-sanity, which provides utilities specifically designed for Next.js applications. This package includes configured clients, image builders, and preview helpers tailored for the Next.js environment. Additional packages include @sanity/image-url for image handling and @sanity/client for core functionality when you need to work outside the Next.js context.

npm install next-sanity @sanity/image-url @sanity/client

Use next-sanity for Next.js projects as it handles server-side rendering concerns and integrates with Next.js caching mechanisms. The @sanity/client package is the core client that works in any JavaScript environment and is included as a dependency of next-sanity. For projects requiring type generation, the Sanity CLI can generate TypeScript types from your schema definitions, ensuring type safety throughout your codebase and providing IDE autocomplete for content structures.

For proper schema design that works well with this setup, see our guide on Sanity Schema Design to build effective content models.

Environment Configuration

Sanity requires several environment variables to connect your Next.js application to your content backend. These credentials are obtained from your Sanity project dashboard at sanity.io/manage and should be managed securely through environment variables.

The NEXT_PUBLIC_SANITY_PROJECT_ID is your unique project identifier that connects to the correct Sanity project. The NEXT_PUBLIC_SANITY_DATASET specifies which dataset to use, typically "production" for live content. The SANITY_API_TOKEN provides API access and should be generated with appropriate permissions based on your use case--read-only for public content fetching, or with write access for preview and editing scenarios. The SANITY_API_VERSION sets a consistent API version date to ensure predictable responses as the API evolves.

Required Environment Variables
VariablePurposeWhere to Find
NEXT_PUBLIC_SANITY_PROJECT_IDUnique project identifiersanity.io/manage
NEXT_PUBLIC_SANITY_DATASETDataset name (usually 'production')sanity.io/manage
SANITY_API_TOKENAPI access token (read/write)sanity.io/manage > API > Tokens
SANITY_API_VERSIONAPI version dateCustom (e.g., '2024-01-01')
lib/sanity.ts - Sanity Client Configuration
1import { createClient } from 'next-sanity';2import imageUrlBuilder from '@sanity/image-url';3 4export const client = createClient({5 projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID!,6 dataset: process.env.NEXT_PUBLIC_SANITY_DATASET || 'production',7 apiVersion: process.env.SANITY_API_VERSION || '2024-01-01',8 useCdn: process.env.NODE_ENV === 'production',9});10 11const builder = imageUrlBuilder(client);12 13export function urlFor(source: SanityImageSource) {14 return builder.image(source);15}
lib/sanity.preview.ts - Preview Client
1import { createClient } from 'next-sanity';2 3export const previewClient = createClient({4 projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID!,5 dataset: process.env.NEXT_PUBLIC_SANITY_DATASET || 'production',6 apiVersion: process.env.SANITY_API_VERSION || '2024-01-01',7 useCdn: false,8 token: process.env.SANITY_API_TOKEN,9});10 11export function getPreviewPost(slug: string) {12 return previewClient.fetch(13 `*[_type == "post" && slug.current == $slug][0]`,14 { slug }15 );16}
app/api/revalidate/route.ts - On-Demand Revalidation
1import { revalidatePath } from 'next/cache';2import { NextRequest, NextResponse } from 'next/server';3 4export async function POST(request: NextRequest) {5 const secret = request.nextUrl.searchParams.get('secret');6 7 if (secret !== process.env.SANITY_REVALIDATE_SECRET) {8 return NextResponse.json({ message: 'Invalid token' }, { status: 401 });9 }10 11 const body = await request.json();12 const { _type, slug } = body;13 14 if (_type === 'post' && slug?.current) {15 revalidatePath(`/blog/${slug.current}`);16 revalidatePath('/blog');17 }18 19 return NextResponse.json({ revalidated: true, now: Date.now() });20}
GROQ Query with Projection
1// Fetch post with author and categories in single query2const postQuery = `*[_type == "post" && slug.current == $slug][0]{3 title,4 publishedAt,5 body,6 "author": author->{name, image, bio},7 "categories": categories[]->title8}`;

Frequently Asked Questions

What is the difference between next-sanity and @sanity/client?

next-sanity provides Next.js-specific utilities like configured clients, image builder, and preview helpers. @sanity/client is the core client that works in any JavaScript environment. Use next-sanity for Next.js projects as it handles server-side rendering and caching integration.

How does ISR differ from standard static generation?

Standard static generation builds all pages at build time. ISR builds pages on-demand and revalidates them in the background, allowing content updates without full rebuilds while maintaining static delivery performance.

What permissions does the API token need for preview mode?

Preview mode requires a token with read access to draft documents. Create a dedicated token in Sanity settings with 'Viewer' or 'Editor' permissions depending on your needs.

Can I use Sanity with both App Router and Pages Router?

Yes, next-sanity supports both Next.js routing systems. The core client and query patterns remain the same, with minor differences in API route handling between App Router (route.ts) and Pages Router (pages/api).

How do I handle images with Sanity in Next.js?

Use the imageUrlBuilder from next-sanity to generate CDN URLs with transformations. Combined with Next.js Image component, this provides responsive images with automatic format optimization and lazy loading. See our [Sanity Image Pipeline](/resources/guides/platform-docs/sanity/sanity-image-pipeline/) guide.

What is the best way to structure Sanity queries for performance?

Use GROQ projection to fetch only needed fields, apply filters early in the query, and leverage references with dereferencing (->) to reduce round trips. For complex queries, see our [Sanity GROQ Queries](/resources/guides/platform-docs/sanity/sanity-groq-queries/) guide.

Ready to Build with Sanity + Next.js?

Explore our comprehensive platform documentation to master headless CMS integration.

Sources

  1. Sanity.io Exchange: Next.js Resources - Official Sanity's Next.js integration resources and plugins
  2. SaaSBold: Sanity Integration Guide - Step-by-step integration tutorial with code examples
  3. Medium: Next.js 15 + Sanity Integration - TypeScript integration guide