Rendering modes — ISR, SSG, SSR
@ghostwritr/next doesn’t impose a caching strategy. You pick your rendering mode with a single revalidate flag on createGhostwritr, and the client folds your choice into Next’s fetch so every feed request — manifest and pages — is cached the way you asked.
import "server-only";import { createGhostwritr } from "@ghostwritr/next/server";
export const gw = createGhostwritr({ siteId: process.env.GHOSTWRITR_SITE_ID!, revalidate: 3600, // <- this flag is the whole story});The three modes
Section titled “The three modes”| You want | revalidate | Behavior under the hood |
|---|---|---|
| ISR (default) | 3600 (any positive N) | next: { revalidate: N } — served from cache, refreshed in the background every N seconds. |
| Pure SSG | false | next: { revalidate: false } — fetched at build, cached indefinitely. Rebuild to update. |
| Dynamic SSR | 0 | cache: "no-store" — fetched on every request. Always live. |
revalidate must be a non-negative integer or false; anything else throws a GhostwritrError with code CONFIG at client-creation time. The default when you omit it is 3600.
createGhostwritr({ siteId, revalidate: 600 }); // ISR, 10-minute windowcreateGhostwritr({ siteId, revalidate: false }); // pure SSGcreateGhostwritr({ siteId, revalidate: 0 }); // dynamic SSRISR — revalidate: N
Section titled “ISR — revalidate: N”The default and the right answer for most blogs. Pages are pre-rendered and served from cache; after N seconds the next request triggers a background refresh, so visitors never wait on the feed.
- Pick it when you want fast static pages but don’t want to redeploy to publish.
- Trade-off new articles appear within the
revalidatewindow, not instantly — tuneNlower for fresher, higher for fewer feed fetches. For true instant publishing, keep a generous window and add instant revalidation.
Pure SSG — revalidate: false
Section titled “Pure SSG — revalidate: false”The feed is fetched once at build and cached forever. The pages are fully static — fastest possible serve, no runtime feed fetches at all.
- Pick it when you rebuild and redeploy on every publish anyway (e.g. you trigger a deploy from the
feed.updatedwebhook), or your content rarely changes. - Trade-off content is frozen until the next build. Without a rebuild, new and edited articles never appear.
Dynamic SSR — revalidate: 0
Section titled “Dynamic SSR — revalidate: 0”Every request fetches the feed fresh (cache: "no-store"). Always live, never stale.
- Pick it when you need real-time freshness and can absorb a feed round-trip per request — a preview environment, or a low-traffic page where caching buys little.
- Trade-off no static caching means every render pays the feed latency, and you lose the CDN-edge speed of static pages.
On-demand revalidation (the best of ISR)
Section titled “On-demand revalidation (the best of ISR)”ISR with a long window plus on-demand busting gives you static speed and instant freshness. Add tags, and a verified feed.updated webhook busts them the moment the engine rebuilds your feed:
export const gw = createGhostwritr({ siteId: process.env.GHOSTWRITR_SITE_ID!, revalidate: 3600, tags: ["ghostwritr"], // <- on-demand revalidation});import { createRevalidateHandler } from "@ghostwritr/next/revalidate";
export const POST = createRevalidateHandler({ secret: process.env.GHOSTWRITR_FEED_SECRET!, tags: ["ghostwritr"],});tags must be an array of strings or you get a CONFIG error. The tags you pass here must match the tags the handler revalidates. See Instant revalidation for the full wiring and Instant updates for the concept.
What to reach for next
Section titled “What to reach for next”- Instant revalidation — the signed webhook that busts your tags on publish.
- SEO metadata & sitemap —
generateMetadataandapp/sitemap.tsfrom the article fields. - API reference — the full
GhostwritrConfig.