By Douwe Pausma
Add custom buttons to your edit views, that trigger custom actions like webhooks!
released September 16, 2026
npm install strapi-plugin-custom-buttonAdd custom buttons to the content-type entry edit view that trigger custom actions: call a webhook or navigate to a URL.
npm install strapi-plugin-custom-buttonConfigure the plugin in your Strapi project's config/plugins.ts (or config/plugins.js):
export default ({ env }) => ({
'custom-button': {
enabled: true,
config: {
cardTitle: 'Actions', // Optional: title of the side panel card
buttons: [
{
id: 'publish-to-cdn',
name: 'Publish to CDN',
icon: 'Cloud', // Optional: icon from @strapi/icons
variant: 'success', // Optional: button variant
action: 'webhook', // Optional: 'webhook' (default) or 'navigate'
url: 'https://api.example.com/webhook/publish',
method: 'POST',
headers: { // Optional
'Authorization': 'Bearer your-token',
'Content-Type': 'application/json',
},
body: (entry) => ({ // Optional: function that receives entry data
contentType: entry.contentType.uid,
documentId: entry.values.documentId,
}),
models: ['api::article.article'], // Optional: limit to specific content-types
},
{
id: 'preview',
name: 'Preview',
icon: 'Eye',
action: 'navigate',
newTab: true, // Optional: open in a new tab (default) or the current one
body: (entry) => `https://example.com/preview/${entry.values.slug}`,
models: ['api::article.article'],
},
],
},
},
});| Option | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique identifier for the button |
name | string | Yes | Display text for the button |
action | 'webhook' | 'navigate' | No | What the button does. Defaults to 'webhook' |
url | string | Webhook only | Webhook URL to call |
method | 'GET' | 'POST' | 'PUT' | 'DELETE' | Webhook only | HTTP method |
headers | Record<string, string> | No | HTTP headers to include (webhook only) |
body | (entry) => object | string | No | Function receiving entry data. For webhooks, returns the request body; for navigation, returns the URL |
newTab | boolean | No | Navigation only: open the URL in a new tab. Defaults to true |
icon | string | No | Icon name from @strapi/icons |
variant | string | No | Button style: 'default', 'secondary', 'tertiary', 'success', 'success-light', 'danger', 'danger-light', 'ghost' |
models | string[] | No | Content-type UIDs to show this button on (shows on all if not specified) |
The body option accepts a function that receives the entry data. For webhook buttons it returns the object to send as the request body:
body: (entry) => ({
contentType: entry.contentType.uid, // e.g., 'api::article.article'
documentId: entry.values.documentId, // The entry's document ID
title: entry.values.title, // Access any field value
// ... any other entry fields
})For navigation buttons it returns the URL to open, either as a string or as an object with a url property:
body: (entry) => `https://example.com/preview/${entry.values.slug}`
// or
body: (entry) => ({ url: `https://example.com/preview/${entry.values.slug}` })Contributions are welcome! Whether it's bug fixes, new features, or documentation improvements, feel free to open an issue or submit a pull request.
If you're interested in working on any of these, we'd love to see your contribution!
MIT
Made in 🇳🇱 by @douwepausma
Share your work with the community and get it listed in the Strapi ecosystem for everyone to discover and use.
Submit
