Sanity content not updating automatically in Next.js without API changes

11 replies
Last updated: Sep 29, 2023
Hi folks.. I need your help with my Sanity implementation to my Next.js site. New published Sanity content is visible on my Next.js site only if I change something in the API call, such as
apiVersion
, so it is not hapenning automaticly as it should.
AI Update

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 thread
11 replies
that's a next js problem. I had to set every query to no-cache and adding
export const dynamic = 'force-dynamic';
to every page.
I am aware that this is terrible solution. I wonder if anyone else has a better way to solve this
😅
unless you are not using app dir. Then you could set revalidate in your
getStaticProps()
I am quite new to all this, so I don´t know how exactly to make these steps, but at least now I know what should I be looking for.. Thank you very much
join NextJs discord server. You can find more help regarding Nextjs spesific things there 😊
I am using app dir, but I dont thing I am using
getStaticProps()
.. I was following this tutorial https://www.youtube.com/watch?v=OcTPaUfay5I and I understood taht you dont need that for this in Next.js 13
try adding this anywhere in the (dynamic) page
export const revalidate = 10
yeah, no with app dir you don't need
getStaticProps
cause app dir handles server side a bit differently.
To clarify
user U
, the
app
and
pages
directories on Next.js will handle things differently, including fetching data. It seems your issue can be solved by the solutions above, but please make a new message if it doesn't, letting us know which Next.js version you're using, as well as which router (
app
or
pages
). Thanks!
I am using Next.js v13.5.3 and it seems that solutions above helped me. I am using app directory and I used every suggestion 🙂• I added
{ cache: 'no-store' }
at the end of every of my Sanity fetch• I added
export const revalidate = 10;
and
export const dynamic = 'force-dynamic';
to my every page.tsx and layout.tsx
It is not superfast.. I have to wait a few seconds, but it is working.. Thank you very much everyone
Glad to hear it's sorted!

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.

Was this answer helpful?