API reference
Every export of @ghostwritr/react-router. The fetchers, the webhook verifier, GhostwritrError, and the types are re-exported from the shared @ghostwritr/feed core, so the contract is identical across the Next / Astro / React Router SDKs. articleMeta is React-Router-specific.
fetchArticles(options)
Section titled “fetchArticles(options)”function fetchArticles(options: FeedFetchOptions): Promise<Article[]>Every published Article for the site, newest first. Resolves the feed manifest, then walks each immutable build page (20 per page) and de-duplicates by id. Returns [] when the feed has zero pages; throws GhostwritrError NOT_FOUND when the site has no feed yet. Call it inside a route loader.
fetchArticle(options)
Section titled “fetchArticle(options)”function fetchArticle( options: FeedFetchOptions & { slug: string },): Promise<Article | null>One published article by slug, read directly from the by-slug document (no page walk), or null when the slug isn’t in the current feed. A blank slug throws GhostwritrError CONFIG. Throw a 404 Response yourself on null — see Writing loaders.
FeedFetchOptions
Section titled “FeedFetchOptions”interface FeedFetchOptions { siteId: string; // the unguessable keyless read key (required) staticBaseUrl?: string; // feed origin override; default DEFAULT_STATIC_BASE_URL fetch?: typeof fetch; // your own fetch (caching/retries/test stub)}articleMeta(article, opts?)
Section titled “articleMeta(article, opts?)”function articleMeta(article: Article, opts?: ArticleMetaOptions): MetaDescriptor[]Builds the React Router MetaDescriptor[] for an article route’s meta export: <title> (from seoTitle), description, Open Graph + Twitter cards, <link rel="canonical">, and schema.org Article JSON-LD. Full breakdown in SEO meta.
ArticleMetaOptions
Section titled “ArticleMetaOptions”interface ArticleMetaOptions { url?: string; // canonical + og:url for THIS page; wins over article.canonicalUrl siteName?: string; // og:site_name + JSON-LD publisher twitterSite?: string; // twitter:site @handle}verifyWebhook(secret, rawBody, headers, opts?)
Section titled “verifyWebhook(secret, rawBody, headers, opts?)”function verifyWebhook( secret: string, rawBody: string, headers: Headers | Record<string, string | null | undefined>, opts?: { toleranceSeconds?: number; now?: number },): Promise<boolean>Verify a signed, replay-safe feed.updated webhook. Reads Webhook-Id / Webhook-Timestamp / Webhook-Signature from the headers object itself, rejects a timestamp outside toleranceSeconds (default 300), and constant-time compares the v1 HMAC of `${id}.${timestamp}.${rawBody}`. Returns false for any missing, stale, or mismatched input. Web Crypto — runs in Node 20+ and on edge. See Feed-freshness webhook.
WEBHOOK_ID_HEADER · WEBHOOK_TIMESTAMP_HEADER · WEBHOOK_SIGNATURE_HEADER
Section titled “WEBHOOK_ID_HEADER · WEBHOOK_TIMESTAMP_HEADER · WEBHOOK_SIGNATURE_HEADER”const WEBHOOK_ID_HEADER = "Webhook-Id"const WEBHOOK_TIMESTAMP_HEADER = "Webhook-Timestamp"const WEBHOOK_SIGNATURE_HEADER = "Webhook-Signature"The three headers carried by every delivery. Webhook-Id is the per-delivery idempotency key (dedupe retries on it); Webhook-Timestamp is unix seconds; Webhook-Signature carries v1=<hex>.
DEFAULT_STATIC_BASE_URL
Section titled “DEFAULT_STATIC_BASE_URL”const DEFAULT_STATIC_BASE_URL = "https://feeds.ghostwritr.io"The default static-feed origin. Override per call with FeedFetchOptions.staticBaseUrl.
GhostwritrError
Section titled “GhostwritrError”class GhostwritrError extends Error { readonly status: number; // HTTP status, or 0 for client-side errors readonly code: GhostwritrErrorCode | null; readonly details?: unknown;}The single error type the fetchers throw. code is one of CONFIG, NETWORK_ERROR, NOT_FOUND, RATE_LIMITED, SERVER_ERROR, INVALID_RESPONSE (and the auth codes UNAUTHORIZED / FORBIDDEN). See Error handling.
Re-exported types
Section titled “Re-exported types”From @ghostwritr/feed, available as type-only imports:
Article— a published article. See The article shape.ArticleImage— the cover image (url,alt,width,height,srcset), ornull.Author— the byline;kindis"real"or"persona"and drives the JSON-LD type.ArticleOrder—"published-desc"(default, newest first) or"feed".FeedFetchOptions— the fetcher options above.FeedUpdatedPayload— the webhook body (event,siteId,buildId).GhostwritrErrorCode— the union of error codes.ArticleMetaOptions— thearticleMetaoptions above (this package’s own type).