You can integrate Builder with your app using webhooks. This can be useful if you want your app to be aware of content changes that should trigger any workflows you have on your end. An example of this could include storing the data that has changed in your database or triggering a cache bust in your CDN.
Often, reasons for using global webhooks include:
- Workflow automation: Automating tasks that should occur in response to various events in Builder.io, such as content publishing or updating.
- Integration with other systems: Syncing content changes with external databases, CMS, personalization engines, or even cache invalidation in CDNs, so that changes in Builder reflect immediately wherever needed.
- Efficiency and scalability: Reducing the need for manual checks or API polling to detect changes, which can be inefficient and not scalable.
To add a webhook for a model:
- Go to Models.
- Choose the model you want to edit.
- Scroll down and choose Show More Options.
- Click Edit Webhooks.
- Enter a URL you would like Builder to
POST
to with the updated content.
Builder will POST
to the endpoint you provide every time content is published, unpublished, archived, or deleted. Note that a null
newValue
indicates a deletion, and a null previousValue
indicates a first publish.
Below is an example of a POST
format:
{
"newValue": {
"id": "cs3df",
"published": "draft",
"name": "My great page",
"data": {
"property": "value"
}
},
"previousValue": { ... },
"modelName": "page",
"operation": "publish"
}
Note that the operation
property can be one of
- publish
- archive
- delete
- unpublish
- scheduledStart
- scheduledEnd
Below is an example of how you might handle incoming webhook data in a Next.js application where you can handle webhooks on the API routes.
Create a file for your webhook handler inside the pages/api
directory of your Next.js project. You might name it webhook.js
for clarity. The path to the file defines the URL path. For example, a file at pages/api/webhook.js
handles requests at /api/webhook
.
Implement the POST
handler in your webhook.js
file. Here's how you might code it:
// pages/api/webhook.js
export default async function handler(req, res) {
// Ensure method is POST
if (req.method === 'POST') {
const { newValue, previousValue } = req.body;
console.log('New Value:', newValue);
console.log('Previous Value:', previousValue);
// Here you can add the logic to process the webhook data
// For example, updating your local database, invalidating cache, etc.
// Respond to the request indicating success
return res.status(200).json({ message: 'Webhook received and processed' });
} else {
// Handle any other HTTP methods
res.setHeader('Allow', ['POST']);
return res.status(405).end(`Method ${req.method} Not Allowed`);
}
}
Make sure that your webhook endpoint is secured:
- Validate incoming requests to make sure they originate from Builder.io.
- Use HTTPS to protect the data in transit.
- Consider rate limiting to protect against abuse. This can sometimes be handled at the infrastructure level, depending on your hosting provider.
Global webhooks in Builder.io are triggered under specific scenarios, primarily focusing on significant state changes of content within your account:
- Publishing content: triggered when content moves from a non-published state (such as draft or archived) to a published state.
- State changes from published: triggered when content that was previously published is now moved to a different state, such as draft or archived.
- Content deletion: triggered when
newValue
isnull
, indicating that content has been deleted. - Initial publishing: triggered when
previousValue
isnull
, indicating that content has been published for the first time. - Scheduled start/end dates: If content is scheduled to be live on a certain date, webhooks associated with that content will be fired on that given date and time.
Importantly, global webhooks do not trigger for routine content updates or modifications within non-published states — such as transitions from draft to archived or deleted.
This precise activation ensures that the webhooks are used for critical notifications, which is particularly useful for workflow automation and synchronizing significant content state changes with external systems.
When you've configured the webhook URL in Settings, Builder sends HTTP POST
requests to the specified URL whenever the defined events occur; for example, content updates.
Your endpoint should be prepared to parse and handle the incoming data, which typically includes fields like newValue
and previousValue
, representing the new and previous states of the content.
The next example demonstrates rendering data.
Suppose you were using webhooks to store Builder content changes to use at render time; for example, side-loading. Each time your app received a webhook from Builder, your app would store the new value in its database.
Then, when your app received a request from a user, it would query its own database for the content instead of hitting the Builder API as requests came in.
If you were using the Builder React SDK to render components or pages on your site, you'd pass the JSON data that came in the webhook,newValue
, to the content
prop of the BuilderComponent
or Content
(depending on your SDK generation) and the component would handle rendering for you, as in the snippet below:
// Gen 1 SDK
import { BuilderComponent } from '@builder.io/react';
<BuilderComponent model="page" content={theJsonFromTheWebhook} />
// Gen 2 SDK
import { Content } from '@builder.io/sdk-react';
<BuilderComponent model="page" apiKey="YOUR_API_KEY" content={theJsonFromTheWebhook} />
You can extend or modify this approach to fit your app's way of rendering data for your users, even if you are not using a Builder-supplied SDK.
Another option if you are not using JavaScript to render your frontend is to have Builder pre-render the HTML for you. Using pre-rendering means you can store the HTML that Builder generates and serve it to your users according to your use case.
When your app gets a webhook from Builder, use the id
supplied in the request to make a call to Builder's HTML API. Then store that HTML in your database and send it to your users in a way that works for your app.
Since this example only calls Builder once every time the app receives a webhook, use the query parameter cachebust=true
to ensure your app gets the most up-to-date data. The response
below uses cachebust=true
:
let response = fetch('https://cdn.builder.io/api/v1/html/DOC_ID?apiKey=YOUR_KEY&cachebust=true')
// Now you can save and later serve the HTML as you please
let html = response.data.html
Tip: Only use cachebust: true
in the SDKs or APIs for build time requests; such as static building pages.
We do not recommend it for runtime requests—such as when serving live pages.