Instant publishing
By default each SDK refreshes on its own clock (Next’s ISR revalidate, an Astro rebuild). To make a just-published article appear in seconds, subscribe to the feed.updated webhook: when the engine rebuilds your site’s static feed it POSTs a small signed body to your registered URL, and your app revalidates on the spot.
Read Instant updates for the concept; this page is the per-framework wiring.
The webhook
Section titled “The webhook”The body is JSON:
{ "event": "feed.updated", "siteId": "your-site-id", "buildId": "..." }The request carries an X-GW-Signature header — a hex HMAC-SHA256 of the raw request body, keyed by a shared secret you set when you register the subscription. Always verify that signature over the raw bytes before you act on the request, or anyone who learns your URL can force-revalidate your cache.
Per framework
Section titled “Per framework”@ghostwritr/next/revalidate ships a ready-made route handler. It verifies the signature, then busts the cache tags (and any paths you list):
import { createRevalidateHandler } from "@ghostwritr/next/revalidate";
export const POST = createRevalidateHandler({ secret: process.env.GHOSTWRITR_FEED_SECRET!, tags: ["ghostwritr"], // default; matches createGhostwritr({ tags }) paths: ["/blog"], // optional: revalidate concrete paths too});For tag-based revalidation to take effect, your data client must tag its fetches. Set the same tag on the client:
import "server-only";import { createGhostwritr } from "@ghostwritr/next/server";
export const gw = createGhostwritr({ siteId: process.env.GHOSTWRITR_SITE_ID!, tags: ["ghostwritr"], // on-demand revalidation target});Register https://your-site.com/api/revalidate as the webhook URL. The full reference is Instant revalidation.
Astro builds the feed into a content collection at build time, so “instant” means trigger a rebuild. Point the webhook at a small endpoint (a serverless function, a CI/CD deploy hook, or an Astro endpoint) that verifies the signature and then kicks your host’s redeploy.
import type { APIRoute } from "astro";import { verifyFeedSignature, FEED_SIGNATURE_HEADER } from "@ghostwritr/feed";
export const POST: APIRoute = async ({ request }) => { const raw = await request.text(); const ok = await verifyFeedSignature( import.meta.env.GHOSTWRITR_FEED_SECRET, raw, request.headers.get(FEED_SIGNATURE_HEADER), ); if (!ok) return new Response("invalid signature", { status: 401 });
// Verified — trigger your host's build/deploy hook: await fetch(import.meta.env.DEPLOY_HOOK_URL, { method: "POST" }); return Response.json({ rebuilding: true });};If you’d rather skip the verifying endpoint entirely, point the webhook straight at your host’s deploy hook URL (Netlify/Vercel/Cloudflare Pages all expose one) — you trade signature verification for one less moving part. The full reference is Redeploy on publish.
React Router renders on each request, so you typically don’t need a webhook at all — a loader that calls fetchArticle is always current. Wire the webhook only if you cache the fetch (CDN, KV) and want to bust that cache on publish. Use a resource route (a route with a loader/action and no default component) and verifyFeedSignature:
import type { Route } from "./+types/feed-updated";import { verifyFeedSignature, FEED_SIGNATURE_HEADER } from "@ghostwritr/react-router";
export async function action({ request }: Route.ActionArgs) { const raw = await request.text(); const ok = await verifyFeedSignature( process.env.GHOSTWRITR_FEED_SECRET!, raw, request.headers.get(FEED_SIGNATURE_HEADER), ); if (!ok) throw new Response("invalid signature", { status: 401 });
// Verified — purge your CDN/KV cache for the affected pages here. return Response.json({ ok: true });}verifyFeedSignature and FEED_SIGNATURE_HEADER are re-exported from @ghostwritr/react-router (they come from the shared feed core). The full reference is Feed-freshness webhook.
What to reach for next
Section titled “What to reach for next”- The concept — what the webhook fires on and the manifest re-fetch it triggers. See Instant updates.
- The signing helpers —
signFeedPayload/verifyFeedSignature/FEED_SIGNATURE_HEADER. See Webhook helpers. - Build a blog — the end-to-end guide this fits into. See Build a blog.