Skip to content

API reference

The complete surface of @ghostwritr/next. Exports are split across three import subpaths — pick the right one or the build will reject a server-only import in a client component.

SubpathExportsWhere it runs
@ghostwritr/next/servercreateGhostwritr (+ re-exports the types and GhostwritrError)Server only (server-only).
@ghostwritr/next/revalidatecreateRevalidateHandlerServer only (imports next/cache).
@ghostwritr/next (root)Types + GhostwritrError + GhostwritrErrorCode. No data client.Client-safe — import anywhere.
import { createGhostwritr } from "@ghostwritr/next/server";
function createGhostwritr(cfg: GhostwritrConfig): Ghostwritr;

Creates a server-side data client. Use as a module singleton in a server-only file. Validates cfg synchronously and throws a GhostwritrError with code CONFIG on bad input.

FieldTypeDefaultNotes
siteIdstringRequired. The unguessable read capability — no API key. Empty/whitespace throws CONFIG.
revalidatenumber | false3600Rendering mode: positive N = ISR every Ns; false = pure SSG; 0 = dynamic SSR (no-store). Must be a non-negative integer or false, else CONFIG. See Rendering modes.
tagsstring[]Cache tags applied to the feed fetch for on-demand revalidation via revalidateTag(). Must be an array of strings, else CONFIG. See Instant revalidation.
staticBaseUrlstringhttps://feeds.ghostwritr.ioStatic feed origin override. Must be a valid URL.
fetchtypeof fetchglobal fetchCustom fetch for retries/proxy or test stubs.
MethodSignatureReturns
getArticlesgetArticles(opts?: { order?: ArticleOrder })Promise<Article[]> — published articles, newest first by default. order: "feed" returns the feed’s native order (also newest-first).
getArticlegetArticle(slug: string)Promise<Article | null> — one article, or null if the slug doesn’t exist.
generateStaticParamsgenerateStaticParams()Promise<Array<{ slug: string }>> — ready to export from a [slug] route.
const articles = await gw.getArticles(); // newest first
const feedOrder = await gw.getArticles({ order: "feed" });
const one = await gw.getArticle("my-post"); // Article | null
export const generateStaticParams = gw.generateStaticParams;
import { createRevalidateHandler } from "@ghostwritr/next/revalidate";
function createRevalidateHandler(opts: {
secret: string;
tags?: string[];
paths?: string[];
}): (req: Request) => Promise<Response>;

Returns a POST route handler that verifies the signed feed.updated webhook (HMAC-SHA256 over the raw body, via the X-GW-Signature header) and then revalidates the given tags and paths. An invalid signature returns 401 and touches nothing; success returns { "revalidated": true }.

OptionTypeDefaultNotes
secretstringRequired. The site’s feed-subscription signing secret (GHOSTWRITR_FEED_SECRET) — distinct from siteId. Empty/whitespace throws CONFIG.
tagsstring[]["ghostwritr"]Tags to revalidateTag(). Must match your createGhostwritr({ tags }).
pathsstring[][]Concrete paths to revalidatePath(), e.g. ["/blog", "/sitemap.xml"].
import { GhostwritrError } from "@ghostwritr/next"; // or /server

The single error class every read throws.

MemberTypeNotes
messagestringHuman-readable.
statusnumberHTTP status, or 0 for client-side/config/network errors.
codeGhostwritrErrorCode | nullStable, branchable code.
detailsunknownOptional context (offending URL, raw payload, network cause).

A string union: "CONFIG", "NETWORK_ERROR", "UNAUTHORIZED", "FORBIDDEN", "NOT_FOUND", "RATE_LIMITED", "SERVER_ERROR", "INVALID_RESPONSE" (open to future codes). See Error handling for what each means and how to branch.

These come from the shared keyless core so they never drift from @ghostwritr/astro. Available from @ghostwritr/next (root) and @ghostwritr/next/server.

TypeShape
Articleid, title, slug, markdown, seoTitle, seoDescription | null, canonicalUrl | null, formatType, inLanguage, tags[], image (ArticleImage | null), author (Author), publishedAt, createdAt, updatedAt. Guaranteed fields are non-null.
ArticleImageurl, alt, width | null, height | null, srcset | null.
Authorname, slug, bio | null, avatarUrl | null, jobTitle | null, sameAs[], kind: "real" | "persona". kind selects Person vs Organization JSON-LD.
ArticleOrder"published-desc" (default, newest first) | "feed" (the feed’s native order).
GhostwritrConfigThe createGhostwritr config — see the table above.
GhostwritrThe returned client interface — getArticles, getArticle, generateStaticParams.
GhostwritrErrorCodeThe error-code union above.

For the full per-field contract and which fields are nullable, see The article shape.