Sync Clerk data to your application with webhooks
You will learn the following:
- Listen for an event in the Clerk Dashboard
- Create a webhook handler that:
- uses Svix to verify the webhook signature
- receives the webhook's payload
- Test the webhook locally using ngrok and the Clerk Dashboard
- Add logic to your application to trigger the webhook
Before you start
The recommended way to sync data between Clerk and your application is to use webhooks.
In this guide, you will learn how to create a Clerk webhook in your Next.js application. You will listen for the user.updated
event by creating a webhook endpoint in the Clerk Dashboard, creating a webhook handler in your Next.js application, and testing the webhook locally using ngrok and the Clerk Dashboard.
This guide can be adapted to listen for any Clerk event.
Set up ngrok
To test a webhook locally, you will need to expose your local server to the internet. For this guide, you will use ngrok. ngrok will create a forwarding URL that you can send your webhook payload to and it will forward the payload to your local server.
- Go to the ngrok website and create an account.
- Once you have made it to the ngrok dashboard, in navigation sidebar, select Domains.
- Select Create domain.
- Install ngrok and add your auth token by following steps 1 and 2 in their install guide.
- ngrok will generate a free, non-ephemeral domain for you and a command to start a tunnel with that domain. The command should look something like this:
ngrok http --domain=fawn-two-nominally.ngrok-free.app 3000
- Change the port number to whatever your server is running on. For this guide, ensure it is set to 3000 and then run the command in your terminal.
- Copy your forwarding URL. It should look something like
https://fawn-two-nominally.ngrok-free.app
.
Create an endpoint in the Clerk Dashboard
To create a webhook endpoint, you must provide the Endpoint URL and then choose the events you want to listen to. For this guide, you will listen to the user.updated
event.
- Navigate to the Clerk Dashboard.
- In the navigation sidenav, select Webhooks.
- Select the Add Endpoint button.
- In the Endpoint URL field, paste the ngrok URL you copied earlier followed by
/api/webhooks
. This is the endpoint that you will later create, that Svix will send the webhook payload to. The full URL should look something likehttps://fawn-two-nominally.ngrok-free.app/api/webhooks
. - In the Message Filtering section, select the
user.updated
event. - Select the Create button.
- You will be redirected to your endpoint's settings page. Leave this page open.
Add your signing secret to your .env.local
file
To verify the webhook payload, you will need your endpoint's signing secret. However, you do not want to expose this secret in your codebase, so you will want to provide it as an environment variable. In local development, this can be done by storing the secret in the .env.local
file.
- On the endpoint's settings page, copy the Signing Secret. It should be on the right side of the page with an eye icon next to it.
- In your project's root directory, you should have an
.env.local
file that includes your Clerk API keys. Here, assign your signing secret toWEBHOOK_SECRET
. Your file should look something like this:
Set webhook route as public in your Middleware
Incoming webhook events will never be signed in -- they are coming from a source outside of your application. Since they will be in a signed out state, the route should be public.
The following example shows the recommended Middleware configuration for your webhook routes.
Install svix
You will use svix
to verify the webhook signature. Run the following command to install it:
Create the endpoint in your application
Create a Route Handler that uses svix
to verify the webhook signature and that receives the webhook's payload.
For the sake of this guide, you will only log the payload to the console. In a real world application, you would use the payload to trigger some action. For example, you are listening for the user.updated
event, so you could perform a database update
or upsert
to update the user's details.
Your webhook will need to return either an error code, or a success code, like 200
or 201
. If it returns an error code, the webhook will reflect that in the Dashboard log and it will retry. When the webhook returns a success code, there will be no retries and the webhook will show a success status in the Dashboard.
Narrow the webhook event to get typing
The WebhookEvent
reflects all possible webhook types. You can narrow down the event to get the types inferred correctly for the event type you are working with.
In the following example, the if
statement will narrow the type to the user.created
type and using evt.data
will give you autocompletion and type safety for that event.
If you want to handle types yourself, you can import the following types from your backend SDK, such as @clerk/nextjs/server
.
DeletedObjectJSON
EmailJSON
OrganizationInvitationJSON
OrganizationJSON
OrganizationMembershipJSON
SessionJSON
SMSMessageJSON
UserJSON
Test your webhook
- Start your Next.js server.
- On your endpoint's settings page in the Clerk Dashboard, select the Testing tab.
- In the Select event dropdown, select
user.updated
. - Select the Send Example button.
- Below that section, in the Message Attempts section, you should see a successful attempt with a status of
200
.
Message failed
If the message failed:
- Select the message.
- Scroll down to the Webhook Attempts section.
- Select the arrow icon the left side.
- Investigate the error. Your solution is going to depend on the error message. See the Debug your webhooks guide for more information.
Trigger your webhook
To trigger the user.updated
event, you can do one of the following:
- You can edit your user in the Dashboard.
- You can use the
<UserProfile />
component in your application to edit your profile.
Once you have updated a user, you should be able to see the webhook's payload logged to your terminal. You can also check the Clerk Dashboard to see the webhook attempt, the same way you did when testing the webhook.
Wrap up
In this guide, you learned how to create a Clerk webhook using Svix. You created a webhook in the Clerk Dashboard to listen for the user.updated
event and created a Route Handler for your webhook endpoint to verify the webhook signature and receive the payload. You tested the webhook locally using ngrok and the Clerk Dashboard to ensure it was configured properly. And lastly, you added logic to your application to actually trigger the user.updated
event. Now, you can do whatever you want with the webhook payload, such as sending a notification to your users, updating a database, or anything else you can think of.
Feedback
Last updated on