Trigger Webhooks in Sanity
Manually trigger external webhooks right from your Studio. Useful for rebuilding your website using static site generator (Astro, SvelteKit, Next.js, 11ty, etc).
By Félix Péault
Install command
npm i sanity-plugin-webhooks-trigger⚡️ Trigger Webhooks in Sanity ⚡️
Trigger external webhooks right in your Sanity Studio.
Useful for rebuilding your website using a static site generator (Astro, SvelteKit, Next.js, Nuxt, 11ty, Jekyll, Hugo, etc).
Motivation
Rebuilding a static site on every single publish is wasteful and noisy, especially when an editor is working through a dozen documents in a row. This plugin gives them one button to press once they are actually done.
For instance, you can trigger a build on Vercel, Netlify, Cloudflare Workers/Pages, GitHub Actions, or any webhook that accepts a plain GET or POST.
Behind the scenes, it stores a document in your Sanity dataset for each webhook, with its name, URL, method (POST/GET) and the encrypted auth token if needed. It also shows the last run status and date.
Openly –and heavily– inspired from sanity-plugin-vercel-deploy by ndimatteo.
External webhooks, not Sanity webhooks
This plugin fires the webhooks you own, and has nothing to do with Sanity's own GROQ-powered webhooks. They solve opposite problems:
| Sanity webhooks | This plugin | |
|---|---|---|
| Who fires | The Content Lake, automatically | An editor, by pressing a button |
| When | On every matching content change | Only when someone decides to |
| Configured | In sanity.io/manage | In the Studio itself |
| Payload | The document that changed | None, just the request |
You can use both: Sanity webhooks to react to content, this plugin to let people say "I'm done editing, ship it".
Installation
# npm
npm i sanity-plugin-webhooks-trigger
# yarn
yarn install sanity-plugin-webhooks-trigger
# pnpm
pnpm i sanity-plugin-webhooks-trigger
# bun
bun i sanity-plugin-webhooks-triggerUsage
Add it as a plugin in sanity.config.ts (or .js):
import {defineConfig} from 'sanity'
import {webhooksTrigger} from 'sanity-plugin-webhooks-trigger'
export default defineConfig({
//...
plugins: [
webhooksTrigger({
// title: 'Deploy',
// text: 'Custom text',
// encryptionSalt: 'replace-me-with-a-strong-string',
// /** Default event type for GitHub repository dispatch webhooks */
// githubEventType: 'webhook-trigger',
// /** Disable the "Trigger All" button when there are multiple webhooks */
// triggerAll: false,
}),
],
})GitHub repository dispatch
Webhooks pointing at api.github.com get a GitHub Event Type field, which has to match your workflow's types — otherwise GitHub accepts the request and silently starts nothing. It falls back to the plugin-level githubEventType, then to webhook-trigger.
on:
repository_dispatch:
types: [deploy-website]The token needs the Contents: read and write permission. For an organisation repository, create the fine-grained token with the organisation as resource owner and have an admin approve it.
Auth tokens
Webhook documents are created with a . in their _id, which keeps them readable only by authenticated users. Set an encryptionSalt to also encrypt the token at rest — generate one with openssl rand -hex 64. Without it, tokens are stored in plain text.
⚠️ The salt ships in your Studio bundle, so encryption protects against a dataset dump, not against someone who can log into your Studio — storing secrets in an app is never really safe. Prefer the least powerful token that does the job: a deploy hook URL needs none at all, while a GitHub PAT for repository_dispatch requires Contents: read and write, which also allows pushing code.
Changing the salt later makes saved tokens undecryptable: runs fail with an explicit error and you have to re-enter each token.
License
MIT © Félix Péault (Flayks)
Develop & test
This plugin uses @sanity/plugin-kit with default configuration for build & watch scripts.
See Testing a plugin in Sanity Studio on how to run this plugin with hotreload in the studio.

