Discussion on cache problem and webhook usage for updating blog posts on Nextjs hosted on Vercel with Sanity.io.
This is a classic Next.js caching issue, not a Sanity problem! The 5-10 minute delay you're seeing is almost certainly due to Next.js's built-in caching layer that isn't being revalidated when you publish content in Sanity.
When you're working locally, you're likely in development mode where Next.js doesn't cache as aggressively, which is why you see updates instantly. But in production on Vercel, Next.js caches pages to improve performance, and those cached pages won't automatically update when you publish content in Sanity.
The Solution: Set up on-demand revalidation
You need to tell Next.js to refresh its cache when content changes in Sanity. Here are your options:
Option 1: Sanity Functions (Modern Approach)
The modern, recommended approach is using Sanity Functions to automatically trigger Next.js revalidation when content changes. Functions are serverless compute that run within Sanity, so you don't need external hosting. They can listen for document changes and call your Next.js revalidation endpoint automatically.
Option 2: Webhooks + Next.js Route Handler (Traditional Approach)
If you prefer the traditional webhook approach, here's how to set it up:
Step 1: Create a Next.js API route for revalidation
For App Router (/app/api/revalidate/route.ts):
import { revalidatePath, revalidateTag } from 'next/cache'
import { NextRequest, NextResponse } from 'next/server'
export async function POST(request: NextRequest) {
const secret = request.nextUrl.searchParams.get('secret')
if (secret !== process.env.REVALIDATION_SECRET) {
return NextResponse.json({ message: 'Invalid secret' }, { status: 401 })
}
// Revalidate specific paths
revalidatePath('/blog')
revalidatePath('/blog/[slug]')
// Or use tags if you've set them up
// revalidateTag('blog-posts')
return NextResponse.json({ revalidated: true, now: Date.now() })
}Step 2: Set up a webhook in Sanity
- Go to sanity.io/manage
- Select your project
- Go to "API" β "Webhooks"
- Create a new webhook pointing to:
https://yourdomain.com/api/revalidate?secret=YOUR_SECRET - Set it to trigger on "Create", "Update", and "Delete" for your blog post document type
Which revalidation method should you use?
revalidatePath()- Use when you know specific URLs that need updating (like/blogor/blog/my-post-slug). Good for simple blogs.revalidateTag()- More flexible if you tag your data fetching. Great for interconnected content where blog posts reference authors, categories, etc. You'd tag your fetch requests likefetch(..., { next: { tags: ['blog-posts'] } })and then revalidate all related content at once.
Additional tips
- Add a secret token to your revalidation endpoint (as shown above) to prevent unauthorized revalidation
- Store the secret in your Vercel environment variables
- You can also set up time-based revalidation as a fallback by adding
revalidate: 600(10 minutes) to your data fetching, but on-demand revalidation is better for immediate updates
The Sanity documentation has a full course on controlling cached content in Next.js that walks through all these approaches in detail. Once you set this up, your production site should update within seconds of publishing, just like in development!
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.