Webhooks

Integrate Leafpad webhooks with Next.js to instantly update blog pages using on-demand ISR revalidation. Avoid periodic cache refreshes and keep your site fast,


Leafpad webhooks allow your application to react instantly when a blog is created or updated. Instead of polling Leafpad or revalidating your site cache on a fixed interval, you can trigger actions only when content actually changes.

This results in:

  • Faster content updates

  • Better cache efficiency

  • Improved overall site performance

How Webhooks Work in Leafpad

Whenever a blog is created or updated in Leafpad, a webhook event is sent to your configured endpoint.

Webhook Payload

Leafpad sends the following JSON payload

{
  "organization": "test",
  "slug": "/how-to-setup-blog",
  "resolvedPath": "/blogs/how-to-setup-blog"
}

Field description:

  • organization – Your Leafpad organization identifier

  • slug – Blog slug in Leafpad

  • resolvedPath – The exact path on your website that should be refreshed.

Use Case: Instant Updates in a Next.js Website

Problem

In a typical setup, a Next.js site using ISR (Incremental Static Regeneration) revalidates pages every few hours:

revalidate: 3600

This means:

  • Updates in Leafpad may take hours to reflect

  • Frequent revalidation increases load unnecessarily


Solution: On-Demand Revalidation via Webhooks

With Leafpad webhooks:

  1. A blog is created or updated in Leafpad

  2. Leafpad sends a webhook to your Next.js backend

  3. Your server revalidates only the affected page

  4. The updated content goes live instantly


Example: Next.js Webhook Handler

Create a secure API route in your Next.js app:

import { revalidatePath } from 'next/cache';
import { NextRequest, NextResponse } from 'next/server';

export async function POST(request: NextRequest) {
  try {
    // Validate authorization token
    const authHeader = request.headers.get('Authorization');
    const token = authHeader?.replace('Bearer ', '');

    if (!token || token !== process.env.REVALIDATE_TOKEN) {
      return NextResponse.json(
        { error: 'Unauthorized' },
        { status: 401 }
      );
    }

    const body = await request.json();
    const { slug, organization, resolvedPath } = body;

    if (!slug) {
      return NextResponse.json(
        { error: 'Slug is required' },
        { status: 400 }
      );
    }

    if (!resolvedPath) {
      return NextResponse.json(
        { error: 'Resolved path is required' },
        { status: 400 }
      );
    }

    // Revalidate the specific page
    revalidatePath(resolvedPath);

    return NextResponse.json(
      {
        success: true,
        message: 'Path revalidated successfully',
        slug,
        organization,
        resolvedPath,
      },
      { status: 200 }
    );
  } catch (error) {
    console.error('Error revalidating path:', error);
    return NextResponse.json(
      {
        error: 'Failed to revalidate path',
        details: error instanceof Error ? error.message : 'Unknown error',
      },
      { status: 500 }
    );
  }
}

Key Benefits of This Approach

  • Instant updates: Content changes reflect immediately

  • Selective revalidation: Only affected pages are refreshed

  • Better performance: No unnecessary background revalidation

  • Scales well: Ideal for content-heavy blogs and documentation sites

Leafpad will save all the webhook requests sent to your server for 1 week and then clear those logs of all the request and response with your server

Published with LeafPad