How to test webhooks on localhost

Testing webhooks on your local system can be difficult, but there are ways to make it possible using tools such as localtunnel and ngrok.

Create an endpoint in your project

The first step in testing webhooks is making sure you have an API endpoint set up in your project. This is the endpoint that’ll receive the webhook event from Liveblocks.

In order to use webhooks, we’ll need to retrieve the headers and body from the request. Here’s the basic endpoint we’ll be starting from:

export async function POST(request: Request) {  const body = await request.json();  const headers = request.headers;
// Handle webhooks // ...
return new Response(null, { status: 200 });}

Create this endpoint in your project, and make it available on localhost at the following URL:

/api/liveblocks-webhook

Testing webhooks locally

Tools such as localtunnel and ngrok allow you to temporarily place your localhost server online, by providing you with a temporary URL. Let’s take a look at these two options.

localtunnel

localtunnel allows you to get started without signing up. If your project is running on localhost:3000, you can run the following localtunnel command to generate your URL, which will stay online while your localhost server is running:

$npx localtunnel --port 3000

localtunnel generates a base URL that can be placed into the Liveblocks webhooks dashboard for quick testing. To use this, take the full address of your webhook endpoint, and replace the domain in your localhost address with the generated URL.

# Take your local URLhttp://localhost:3000/api/liveblocks-webhook
# Replace localhost with the generated domain, then copy ithttps://my-localtunnel-url.loca.lt/api/liveblocks-webhook

You now have a URL that can be used in the webhooks dashboard.

ngrok

ngrok requires you to sign up and install, but it has more features and is simpler to use after you’ve created an account. If your project is running on localhost:3000, you can run the following ngrok command to generate your URL, which will stay online while your localhost server is running:

$ngrok http 3000

ngrok generates a base URL that can be placed into the Liveblocks webhooks dashboard for quick testing. To use this, take the full address of your webhook endpoint, and replace the domain in your localhost address with the generated URL.

# Take your local URLhttp://localhost:3000/api/liveblocks-webhook
# Replace localhost with the generated domain, then copy ithttps://my-localtunnel-url.loca.lt/api/liveblocks-webhook

You now have a URL that can be used in the webhooks dashboard.

Set up webhooks on the Liveblocks dashboard

To use webhooks, you need to pass your endpoint URL to the webhooks dashboard inside your Liveblocks project, and tell the webhook to trigger on any specific webhook events.

  1. Select your project

    From the Liveblocks dashboard, navigate to the project you’d like to use with webhooks, or create a new project.

    Create a Liveblocks project
  2. Go to the webhooks dashboard

    Click on the “Webhooks” tab on the menu at the left.

    Click webhooks
  3. Create an endpoint

    Click the “Create endpoint…” button on the webhooks dashboard to start setting up your webhook.

    Click add endpoint
  4. Add your endpoint URL

    Enter the URL of the endpoint. In a production app this will be the real endpoint, but for now enter your localtunnel or ngrok URL from earlier.

    You can filter for any specific webhook events here, in case you’d only like to listen to certain types.

    Add endpoint URL
  5. Get your secret key

    Click “Create endpoint” at the bottom, then find your “Webhook secret key” on the next page, and copy it.

    Copy your webhook secret key
  6. Webhooks dashboard is set up!

    Done! Let’s go back to the code.

Verify the webhook request

It’s recommended to verify that your webhook requests have come from Liveblocks, and the @liveblocks/node package provides you with a function that will verify this for you. You can set this up by creating a WebhookHandler and running verifyRequest.

Make sure to add your "Webhook secret key" from the Liveblocks dashboard—in a real project we’d recommend using an environment variable for this.

import { WebhookHandler } from "@liveblocks/node";
// Add your webhook secret key from a project's webhooks dashboardconst WEBHOOK_SECRET = "YOUR_WEBHOOK_SECRET";const webhookHandler = new WebhookHandler(WEBHOOK_SECRET);
export async function POST(request: Request) { const body = await request.json(); const headers = request.headers;
// Verify if this is a real webhook request let event; try { event = webhookHandler.verifyRequest({ headers: headers, rawBody: JSON.stringify(body), }); } catch (err) { console.error(err); return new Response("Could not verify webhook call", { status: 400 }); }
// Use webhook event // ...
return new Response(null, { status: 200 });}

The webhook has now been verified!

Use your webhook event

From this point on, you can use the webhook event as you like. Here’s a Comments example, showing you how to fetch a new thread after it’s just been created.

import { WebhookHandler } from "@liveblocks/node";import { Liveblocks } from "@liveblocks/node";
// Add your webhook secret key from a project's webhooks dashboardconst WEBHOOK_SECRET = "YOUR_WEBHOOK_SECRET";const webhookHandler = new WebhookHandler(WEBHOOK_SECRET);
// Add your secret key from a project's API keys dashboardconst API_SECRET = "";const liveblocks = new Liveblocks({ secret: API_SECRET });
export async function POST(request: Request) { const body = await request.json(); const headers = request.headers;
// Verify if this is a real webhook request let event; try { event = webhookHandler.verifyRequest({ headers: headers, rawBody: JSON.stringify(body), }); } catch (err) { console.error(err); return new Response("Could not verify webhook call", { status: 400 }); }
// When a new thread has been created if (event.type === "threadCreated") { const { roomId, threadId } = event.data;
// Fetch new thread const thread = await liveblocks.getThread({ roomId, threadId });
// Use thread // ... }
return new Response(null, { status: 200 });}

Visit the webhook events section of our webhooks guide to learn more.