Strapi Webhook Integration Setup
Strapi sends webhooks when entries are created, updated, and deleted. This is the primary mechanism for integrating with external systems and invalidating frontend cache.
Setting up Webhooks in Admin
Settings → Webhooks → Add new webhook:
- Name: Next.js Revalidation
-
URL:
https://mysite.com/api/revalidate -
Headers:
{ "x-webhook-secret": "my-secret" } -
Events: select
entry.create,entry.update,entry.publish
Webhook via Code
// config/functions/bootstrap.js
// Programmatic webhook registration
module.exports = async ({ strapi }) => {
await strapi.query('webhook').create({
data: {
name: 'CRM Sync',
url: process.env.CRM_WEBHOOK_URL,
headers: { 'Authorization': `Bearer ${process.env.CRM_TOKEN}` },
events: ['entry.create', 'entry.update'],
enabled: true,
},
})
}
Webhook Event Structure
{
"event": "entry.update",
"createdAt": "2024-01-15T10:30:00.000Z",
"model": "article",
"uid": "api::article.article",
"entry": {
"id": 42,
"title": "Updated Title",
"slug": "updated-title",
"publishedAt": "2024-01-15T10:30:00.000Z"
}
}
Webhook Handler in Next.js
// app/api/webhooks/strapi/route.ts
import { revalidateTag, revalidatePath } from 'next/cache'
export async function POST(req: Request) {
const secret = req.headers.get('x-webhook-secret')
if (secret !== process.env.STRAPI_WEBHOOK_SECRET) {
return Response.json({ error: 'Unauthorized' }, { status: 401 })
}
const body = await req.json()
const { model, event, entry } = body
console.log(`Strapi webhook: ${event} on ${model}`, entry?.id)
// Invalidate cache by model
revalidateTag(model)
// Invalidate specific page
const pathMap: Record<string, (entry: any) => string> = {
article: (e) => `/articles/${e.slug}`,
page: (e) => `/${e.slug}`,
category: (e) => `/categories/${e.slug}`,
}
if (pathMap[model] && entry?.slug) {
revalidatePath(pathMap[model](entry))
}
// For homepage/settings — invalidate entire site
if (['global', 'homepage', 'settings'].includes(model)) {
revalidatePath('/', 'layout')
}
return Response.json({ revalidated: true })
}
Slack Integration
// Notifications for new comments
module.exports = (config, { strapi }) => ({
async afterCreate(event) {
const { result } = event
if (event.model.uid === 'api::comment.comment') {
await fetch(process.env.SLACK_WEBHOOK_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
text: `New comment from ${result.author}: "${result.text.slice(0, 100)}"`,
}),
})
}
},
})
Timeline
Setting up webhooks and ISR integration with Next.js — 0.5–1 day. Complex integrations with CRM/ERP — 2–3 days.







