Instant updates
The content feed changes only when you publish. Instead of waiting on a revalidation timer, you can subscribe to a signed webhook and refresh the instant a rebuild lands.
The feed.updated webhook
Section titled “The feed.updated webhook”When a site’s static feed rebuilds, Ghost Writr POSTs a small JSON body to your registered URL:
interface FeedUpdatedPayload { event: "feed.updated"; siteId: string; buildId: string;}buildId is the new build the manifest now points at. Your handler doesn’t need to trust the body’s contents beyond “something changed” — the next read resolves the manifest and picks up the new build automatically. Your job is just to invalidate whatever cached the previous build.
Verify the signature
Section titled “Verify the signature”The request carries X-GW-Signature: a hex HMAC-SHA256 of the raw request body under a shared secret. Verify it against the raw bytes before acting — parsing the body first and re-serializing it will not match.
import { verifyFeedSignature, FEED_SIGNATURE_HEADER } from "@ghostwritr/feed";
const raw = await request.text(); // the RAW body — verify before JSON.parseconst ok = await verifyFeedSignature( process.env.GHOSTWRITR_FEED_SECRET!, raw, request.headers.get(FEED_SIGNATURE_HEADER),);if (!ok) return new Response("invalid signature", { status: 401 });
const { siteId, buildId } = JSON.parse(raw); // now safe to parseverifyFeedSignature is constant-time and returns false for a missing or mismatched signature. The same helpers (signFeedPayload / verifyFeedSignature / FEED_SIGNATURE_HEADER) are re-exported from @ghostwritr/feed, @ghostwritr/next, and @ghostwritr/react-router, so both ends sign identically by construction. They run on Web Crypto — the same in Node 20+ and on the edge.
Three freshness strategies
Section titled “Three freshness strategies”How you refresh depends on how your site renders. Each SDK has a dedicated page for the wiring.
| Render model | Strategy | What the handler does |
|---|---|---|
| Next.js (ISR) | On-demand revalidation | Verify, then revalidateTag / revalidatePath so the next request re-fetches. See Next instant revalidation. |
| Astro (static) | Redeploy hook | Verify, then trigger a rebuild/redeploy of the static site so the new build is generated. See Astro: redeploy on publish. |
| React Router / SSR | CDN purge | Verify, then purge the affected paths from your CDN/cache so the edge re-fetches the feed. See React Router feed-freshness webhook. |
The throughline is the same: verify the signature, then invalidate the cache layer your renderer relies on. The next read walks the manifest and serves the new buildId.