Sanity Studio changes not updating on deployed Vercel staging site
Based on your description, this is a classic caching issue with Next.js and Sanity. The reason your localhost sees updates immediately while your staging site doesn't is because of how Next.js handles data fetching in development vs. production.
What's happening
In development (localhost:3000): Next.js fetches fresh data from Sanity on every page request, which is why you see changes immediately whether you update content locally or from your organization's hosted studio.
In production (your staging site): Next.js serves cached/pre-built pages and doesn't automatically know when content in Sanity has changed. That's why you only see updates after manually pushing code and triggering a new build.
The solution
You need to implement one of these approaches to tell your Next.js site when to refresh content:
1. On-Demand Revalidation with Sanity Functions (Recommended)
The modern approach is using Sanity Functions to trigger Next.js revalidation when content changes. This is better than webhooks because it's native to Sanity and doesn't require external hosting.
Create a Sanity Function that calls your Next.js revalidation endpoint when documents change. Then create an API route in Next.js like:
// pages/api/revalidate.js (or app/api/revalidate/route.js for App Router)
export default async function handler(req, res) {
// Validate the request (check for secret token)
if (req.query.secret !== process.env.REVALIDATE_SECRET) {
return res.status(401).json({ message: 'Invalid token' })
}
try {
await res.revalidate('/') // Revalidate homepage
await res.revalidate('/products') // Revalidate specific paths
// Add more paths as needed
return res.json({ revalidated: true })
} catch (err) {
return res.status(500).send('Error revalidating')
}
}2. Time-Based ISR (Simpler but less immediate)
Add a revalidate value to your data fetching. For the ISR (Incremental Static Regeneration) approach, if you're using the Pages Router:
export async function getStaticProps() {
const data = await client.fetch(query)
return {
props: { data },
revalidate: 60 // Regenerate page every 60 seconds
}
}Or in App Router with the newer sanityFetch:
const posts = await sanityFetch({
query: POSTS_QUERY,
revalidate: 60 // Check for updates every 60 seconds
})3. Important: Disable Sanity's CDN for ISR
When using ISR, set useCdn: false in your Sanity client configuration. The Sanity CDN can interfere with ISR by serving cached data even when Next.js tries to revalidate:
const client = createClient({
projectId: 'your-project-id',
dataset: 'production',
useCdn: false, // Disable CDN for ISR
apiVersion: '2024-01-01',
})Quick diagnostic
Check your existing code for:
- Any
getStaticPropsfunctions - do they have arevalidateproperty? - Your Sanity client config - is
useCdnset totrue? - Any API routes in
/pages/api/or/app/api/that handle revalidation - Webhook configurations in your Sanity project settings
Since this is based on the Next.js eCommerce starter, it likely uses static generation but may not have revalidation configured. The quickest fix is adding time-based ISR with revalidate, though on-demand revalidation with Sanity Functions gives you instant updates when content changes.
Show original thread5 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.