Sanity content not updating automatically in Next.js without API changes
This is a classic Next.js caching issue! Your new Sanity content is being cached by Next.js, so you're seeing stale data until you force a rebuild by changing something like the apiVersion. Let me help you fix this.
The Problem
Next.js aggressively caches data fetches by default, including your Sanity queries. When you publish new content in Sanity, Next.js doesn't know about it and keeps serving the cached version.
The Solution: Use Cache Tags + Revalidation
The modern approach with next-sanity is to use cache tags with the sanityFetch helper function. Here's how:
1. Set up sanityFetch with tags
import { sanityFetch } from '@/sanity/lib/client'
// In your component or page
const posts = await sanityFetch({
query: POSTS_QUERY,
tags: ['post', 'author', 'category'], // Cache tags
})For individual documents, use specific tags:
const post = await sanityFetch({
query: POST_QUERY,
params: { slug: params.slug },
tags: [`post:${params.slug}`], // Specific document tag
})2. Set up automatic revalidation
You have two options for triggering revalidation when content changes:
Option A: Sanity Functions (Recommended)
Use Sanity Functions to automatically call Next.js revalidateTag when content changes. This is the modern approach - serverless compute that runs on Sanity's infrastructure, no external hosting needed. Functions can trigger on document publish/update/delete events and call your Next.js revalidation endpoint directly.
Option B: Webhook + API Route
Create a Next.js API route that revalidates tags:
// app/api/revalidate/route.ts
import { revalidateTag } from 'next/cache'
import { parseBody } from 'next-sanity/webhook'
export async function POST(req: Request) {
const { isValidSignature, body } = await parseBody(req, process.env.SANITY_WEBHOOK_SECRET)
if (!isValidSignature) {
return new Response('Invalid signature', { status: 401 })
}
if (body._type) {
revalidateTag(body._type) // Revalidate by document type
}
return new Response('Revalidated', { status: 200 })
}Then set up a GROQ-powered webhook in your Sanity project settings pointing to https://yoursite.com/api/revalidate.
3. Alternative: Time-based Revalidation
If you prefer simpler time-based updates (without webhooks or functions):
const posts = await sanityFetch({
query: POSTS_QUERY,
revalidate: 60, // Revalidate every 60 seconds
})Note: If you use tags, the revalidate parameter is ignored. Time-based revalidation is part of Next.js's ISR (Incremental Static Regeneration) feature.
Quick Fix for Testing
If you just want to disable caching during development:
const posts = await sanityFetch({
query: POSTS_QUERY,
revalidate: 0, // No caching
})The tag-based approach with Sanity Functions or webhooks gives you the best of both worlds: aggressive caching for performance + instant updates when content changes. This is the recommended pattern for production Next.js + Sanity sites.
Show original thread11 replies
Sanity – Build the way you think, not the way your CMS thinks
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.