API

Server engine

createCMS options and calling the engine directly from loaders and jobs.


createCMS(options) returns { engine, router }. Options:

  • db: a Drizzle database over D1 or SQLite

  • bucket: an R2-compatible bucket (storage from void/storage); enables media

  • site: { specValidator, specGuide, themeSchema }

  • hooks: named custom hooks for { type: "custom", name }

  • jsonSchemas: named zod schemas for json fields

  • collections: extra collections defined in code, read-only to D1 and AI

  • mediaPath: where media is served, default /api/_media

The engine

Engine methods take the acting user first (or null) and return T | CMSError instead of throwing. REST, MCP, and your own code share the same checks.

import { CMSError } from "@interactive-inc/cms"

const engine = createSiteCMS().engine
const page = await engine.resolvePage(null, { path: "/blog/hello" })

if (page instanceof CMSError) return page
if (page === null) return notFound()

const published = await engine.processScheduledPublishes()
const delivered = await engine.processOutbox(deliverOutboxEvent)