Using on-demand revalidation with Next JS and Sanity, how to revalidate all paths when a specific schema type changes.

6 replies
Last updated: May 3, 2023
Hey all,
I am trying to use
on-demand revalidation with Next JS and Sanity.I have most of this setup so far, but I have one issue.
My goal is to have the entire app revalidate when one schema type,
navigation, is changed. Because they are schema for the nav links on all pages in the app.
In the docs, it asks that you explicitly tell Next which routes to revalidate. Like so:
await res.revalidate('/path-to-revalidate');
However, because I want to revalidate every path, I’m not sure what would be the best approach to take.
If anyone has any ideas here, could you help me out?
AI Update

Great question! For revalidating your entire Next.js app when your navigation schema changes, you have a few solid approaches:

Best Solution: Use revalidatePath with Layout Parameter

The simplest approach is to use revalidatePath with the layout parameter, which will revalidate all routes under a given path:

import { revalidatePath } from 'next/cache'

export async function POST(req) {
  // Your webhook validation logic here
  
  // Revalidate all routes in your app
  revalidatePath('/', 'layout')
  
  return NextResponse.json({ revalidated: true, now: Date.now() })
}

The 'layout' parameter tells Next.js to revalidate all pages that share that layout, which effectively means your entire app when you use '/'.

Alternative: Use revalidateTag for Navigation

If you're using tag-based revalidation, you can tag all your queries with a navigation tag and revalidate that single tag:

// In your data fetching
const data = await sanityFetch({
  query: YOUR_QUERY,
  tags: ['navigation', 'post'], // Add navigation tag to all queries
})

// In your revalidation API route
import { revalidateTag } from 'next/cache'

export async function POST(req) {
  const body = await req.json()
  
  if (body._type === 'navigation') {
    revalidateTag('navigation') // Revalidates everything tagged with 'navigation'
  }
  
  return NextResponse.json({ revalidated: true })
}

This is particularly elegant because it revalidates all pages that depend on navigation data without touching pages that don't.

Setting Up the Webhook

To trigger this automatically when your navigation changes, set up a GROQ-powered webhook in your Sanity project that filters for your navigation schema:

_type == "navigation"

Point it to your Next.js API route (e.g., /api/revalidate).

The revalidatePath('/', 'layout') approach is probably your best bet since it's straightforward and ensures everything gets updated when navigation changes. Tag-based revalidation gives you more granular control if you want to optimize which pages actually get revalidated based on which content types they depend on.

I cannot account for whether they're good ideas but if that was my need or use case, I would try either having all the pages on a revalidation timer instead or, to more tightly track/mirror you content updates, trigger a redeploy (you might not be hosted at Vercel but most places that can run Next have a similar mechanism).
Since it doesn't make your site experience any downtime, and just switches things out once it's complete, and absolutely will change all the paths, that might be the cleanest thing.

I don't believe there's a built-in mechanism to target multiple pages, or even pattern-match paths for this one feature.
That is really interesting about the Deploy Hook - thank you
It would be especially nice if I could trigger this to happen only when two specific field changes, slug or title
One thing to think about as well, if it's a possible alternative and to your tastes, is rendering a nav conventionally by default, and then when 'hydrating' after the fact update it a bit.
For example, on the Headspace website (at least as of a month ago) if you're logged out it's one thing, but if you're logged in and return to the homepage, it's normal at first and then account-specific options load in.

As someone else pointed out, too, the
https://www.sanity.io/ homepage itself, in the very bottom footer, keeps high-level organization mostly the same but loads in the live values for submenu items on hover.
Perhaps there's a graceful approach like that, if you can find a way to make it not too distracting, that could accommodate your use case.
I will look into that as well. Thank you for all of your help 😄
It's my pleasure!

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?