clerk-webhooks

安装量: 2.2K
排名: #846

安装

npx skills add https://github.com/clerk/skills --skill clerk-webhooks

Prerequisite: Webhooks are asynchronous. Use for background tasks (sync, notifications), not synchronous flows.

Documentation Reference

| Overview | https://clerk.com/docs/guides/development/webhooks/overview

| Sync to database | https://clerk.com/docs/guides/development/webhooks/syncing

| Debugging | https://clerk.com/docs/guides/development/webhooks/debugging

| Event catalog | https://dashboard.clerk.com/~/webhooks (Event Catalog tab)

Quick Start

  • Create endpoint at app/api/webhooks/route.ts

  • Use verifyWebhook(req) from @clerk/nextjs/webhooks

  • Dashboard → Webhooks → Add Endpoint

  • Set CLERK_WEBHOOK_SIGNING_SECRET in env

  • Make route public (not protected by middleware)

Supported Events

User: user.created user.updated user.deleted

Organization: organization.created organization.updated organization.deleted

Organization Domain: organizationDomain.created organizationDomain.updated organizationDomain.deleted

Organization Invitation: organizationInvitation.created organizationInvitation.accepted organizationInvitation.revoked

Organization Membership: organizationMembership.created organizationMembership.updated organizationMembership.deleted

Roles: role.created role.updated role.deleted

Permissions: permission.created permission.updated permission.deleted

Session: session.created session.updated session.ended session.removed session.revoked session.pending

Communication: email.created sms.created

Invitations: invitation.created invitation.accepted invitation.revoked

Waitlist: waitlistEntry.created waitlistEntry.updated

Full catalog: Dashboard → Webhooks → Event Catalog

When to Sync

Do sync when:

  • Need other users' data (social features, profiles)

  • Storing extra custom fields (birthday, country, bio)

  • Building notifications or integrations

Don't sync when:

  • Only need current user data (use session token)

  • No custom fields (Clerk has everything)

  • Need immediate access (webhooks are eventual consistency)

Key Patterns

Make Route Public

Webhooks come unsigned. Route must be public:

Ensure clerkMiddleware() doesn't protect /api/webhooks(.*) path.

Verify Webhook

Use correct import and single parameter:

import { verifyWebhook } from '@clerk/nextjs/webhooks'
const evt = await verifyWebhook(req)  // Pass request directly

Type-Safe Events

Narrow to specific event:

if (evt.type === 'user.created') {
  // TypeScript knows evt.data structure
}

Handle All Three Events

Don't only listen to user.created. Also handle user.updated and user.deleted.

Queue Async Work

Return 200 immediately, queue long operations:

await queue.enqueue('process-webhook', evt)
return new Response('Received', { status: 200 })

Webhook Reliability

Retries: Svix retries failed webhooks for up to 3 days. Return 2xx to succeed, 4xx/5xx to retry.

Replay: Failed webhooks can be replayed from Dashboard.

Common Pitfalls

| Verification fails | Wrong import or usage | Use @clerk/nextjs/webhooks, pass req directly

| Route not found (404) | Wrong path | Use /api/webhooks

| Not authorized (401) | Route is protected | Make route public

| No data in DB | Async job pending | Wait/check logs

| Duplicate entries | Only handling user.created | Also handle user.updated

| Timeouts | Handler too slow | Queue async work

Testing & Deployment

Local: Use ngrok to tunnel localhost:3000 to internet. Add ngrok URL to Dashboard endpoint.

Production: Update webhook endpoint URL to production domain. Copy signing secret to production env vars.

返回排行榜