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.
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.
| Variable | Purpose | Where to Find |
|---|---|---|
| NEXT_PUBLIC_SANITY_PROJECT_ID | Unique project identifier | sanity.io/manage |
| NEXT_PUBLIC_SANITY_DATASET | Dataset name (usually 'production') | sanity.io/manage |
| SANITY_API_TOKEN | API access token (read/write) | sanity.io/manage > API > Tokens |
| SANITY_API_VERSION | API version date | Custom (e.g., '2024-01-01') |
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}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}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}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.
Sources
- Sanity.io Exchange: Next.js Resources - Official Sanity's Next.js integration resources and plugins
- SaaSBold: Sanity Integration Guide - Step-by-step integration tutorial with code examples
- Medium: Next.js 15 + Sanity Integration - TypeScript integration guide