Back to blog

Published on Monday, February 3, 2025

On-Demand Revalidation for Dynamic Routes in Next.js with Sanity CMS

On-Demand Revalidation for Dynamic Routes in Next.js with Sanity CMS

Introduction

Dynamic content updates in a CMS-powered website require efficient caching strategies. Next.js offers on-demand revalidation, allowing you to update specific content instantly. This article explores how to set up on-demand revalidation for dynamic routes in Next.js with Sanity CMS.

Why On-Demand Revalidation?

By default, Next.js caches data, meaning users might see stale content after an update. With on-demand revalidation, you can purge the cache for specific routes when content changes, ensuring the latest data is displayed without a full site rebuild.

Step 1: Configure Dynamic Route

Ensure your dynamic route fetches fresh data upon revalidation.

// app/blog/[slug]/page.tsx
// NOTE: Adjust important statement according to your project structure
import { sanityClient } from '@/lib/sanity'

interface PageProps {
  params: Promise<{ slug: string }>;		
}

type Post = {
  title: string;
  description: string;
}

export default async function Post(
  { params }: PageProps
) {
  const { slug } = await params;
  const query = `*[_type == 'post' && slug.current == $slug][0] { 
    title,
    description
  }`;
  const post = await sanityClient.fetch<Post>(query, { slug });

  return (
    <main className="p-5">
      <h1 className="text-3xl font-semibold">
        {post.title}
      </h1>
      <p>{post.description}</p>
    </main>
  )
}

Step 2: Configure API Route for Revalidation

Create an API route in your Next.js project to trigger the revalidation process.

// app/api/revalidate/route.ts
import { revalidatePath } from 'next/cache'
import { NextRequest, NextResponse } from 'next/server'

export async function POST(
  req: NextRequest
) {
  const body = await req.json();
		
  // Extract the slug from the request body
  const slug = body.slug; 
		
  try {
    // Revalidate the specific page
    await revalidatePath(`/blog/${slug}`);
		
    return NextResponse.json({
      message: 'Revalidated successfully'
    });
  } catch (error) {
    console.error(error)
    
    return NextResponse.json(
      { message: 'Revalidation failed' },
      { status: 500 }
    );
  }
}

Step 3: Connect Sanity CMS Webhook

In Sanity CMS, set up a webhook that triggers the Next.js API route when content is updated. Navigate to Project Settings > API > Webhooks and configure:

FieldValue
NameNext.js Revalidation
DescriptionTriggers revalidation for updated posts
URLhttps://[domain-name].com/api/revalidate
Datasetproduction
Trigger onUpdate
Filter_type == "post"
Projection{ "slug": slug.current }
StatusEnable webhook
Advanced settings > HTTP methodPOST
Secret[secret-key]

Step 4 (Optional): Secure Your Webhook

To enhance security, use the @sanity/webhook package to validate webhook requests.

Install the package:

npm install @sanity/webhook

Generate a secure token:

node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"

Add the token to your .env.local file:

SANITY_POST_REVALIDATION_WEBHOOK_TOKEN=<your-generated-token>

Then, implement the secure webhook handler:

// app/api/revalidate/route.ts
import { revalidatePath } from 'next/cache'
import { NextRequest, NextResponse } from 'next/server'
import {
  isValidSignature,
  SIGNATURE_HEADER_NAME
} from '@sanity/webhook'

export async function POST(
  req: NextRequest
) {
  // Extract sanity signature from req headers
  const signature = req.headers.get(SIGNATURE_HEADER_NAME) || ""
	
  // Extract the slug from the request body
  const body = await req.json();
  const slug = body.slug;
		
  // Get the secret token from .env file
  const secret = process.env.SANITY_REVALIDATION_WEBHOOK_TOKEN!
		
  // If token is valid, proceed with the API logic
  if (!(await isValidSignature(body, signature, secret))) {
    return NextResponse.json(
      { message: "Invalide signature" },
      { status: 401 }
    )
  }

  try {
    // Revalidate the specific page
    await revalidatePath(`/blog/${slug}`);
	
    return NextResponse.json({ 
      message: 'Revalidated successfully'
    });
  } catch (error) {
    console.error(error)

    return NextResponse.json(
      { message: 'Revalidation failed' },
      { status: 500 }
    );
  }
}

Step 5: Testing On-Demand Revalidation

  • Update an existing post in Sanity CMS.
  • The webhook triggers the Next.js API route.
  • The specific page cache is purged, and fresh content appears instantly.
  • If you implement validation on your revalidate route, check that it works correctly.

Conclusion

On-demand revalidation in Next.js with Sanity CMS enables dynamic, real-time content updates without requiring a full site rebuild. Implementing this approach enhances performance and ensures users always see the latest information.

By following this guide, you can integrate efficient caching strategies while maintaining up-to-date content seamlessly. 🚀