
Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag storeGreat question! This is a common setup for Sanity + Next.js sites, and there are several proven approaches to handle static production deployments with dynamic previews. Here's how people typically handle this workflow:
Production (Static on S3): Use Next.js Static Export (output: 'export') to generate a fully static site that you deploy to S3/CloudFront. This queries Sanity's published content.
Preview Site (Dynamic): Host a separate Next.js instance (on Vercel, Netlify, or any Node.js host) that runs in dynamic mode and uses Next.js Draft Mode to show unpublished drafts from Sanity.
You have a few solid options for controlling when your static site gets rebuilt:
Set up a Sanity webhook that triggers your build pipeline when content changes. Webhooks are GROQ-powered, so you can filter them to only fire on published documents (not drafts) using filters like !(_id in path("drafts.**")). This gives you precise control over when production updates happen.
Your webhook can call your CI/CD pipeline (GitHub Actions, AWS CodeBuild, etc.) to rebuild and deploy to S3. You can also customize the webhook payload using GROQ projections to include exactly the data your build process needs.
Sanity Functions are serverless functions that run on Sanity's infrastructure and can react to document events. They're currently an experimental feature with APIs subject to change, but they offer a way to trigger your deployment pipeline without hosting your own webhook endpoint.
Functions can listen for document publish events and call your CI/CD API to kick off a rebuild. The main advantage is that everything stays within your Sanity project, but be aware this feature is still evolving.
For smaller teams or less frequently updated content, you might just trigger builds manually through your CI/CD dashboard when ready to publish. Simple and reliable!
For the preview site, set up an API route that enables Draft Mode:
// app/api/draft/route.ts
import { draftMode } from 'next/headers'
import { redirect } from 'next/navigation'
export async function GET(request: Request) {
const { searchParams } = new URL(request.url)
const secret = searchParams.get('secret')
const slug = searchParams.get('slug')
// Validate secret token
if (secret !== process.env.SANITY_PREVIEW_SECRET) {
return new Response('Invalid token', { status: 401 })
}
draftMode().enable()
redirect(slug || '/')
}Then in your data fetching, use Sanity's perspective API to fetch drafts when in preview mode:
const client = createClient({
// ...config
perspective: draftMode().isEnabled ? 'previewDrafts' : 'published',
useCdn: !draftMode().isEnabled
})You can add a "Preview" button in Sanity Studio that links editors to your preview site with the draft mode URL, making it seamless for content creators to see their changes before publishing.
If you're open to hosting your production site somewhere that supports server-side features (not pure S3), consider using Incremental Static Regeneration (ISR) instead. This lets you:
With ISR, you'd use revalidateTag() or revalidatePath() in an API route triggered by Sanity webhooks for instant updates when content changes. This eliminates the wait time for full rebuilds while keeping most of the benefits of static generation.
Your S3 static export approach is totally valid—especially if you want zero server costs and maximum simplicity. The most common pattern is:
This gives you full control over the production deployment timing while keeping the preview experience smooth for your content team!
Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.
Content operations
Content backend


The only platform powering content operations
By Industry


Tecovas strengthens their customer connections
Build and Share

Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag store