Configuration
The full shape of cms.config.ts and what each project-owned file in src/cms/ is for. Options link to the page that covers them.
cms.config.ts
Section titled “cms.config.ts”import { defineConfig } from "@kidecms/core";import users from "./collections/users";import pages from "./collections/pages";
export default defineConfig({ locales: { default: "en", supported: ["en"] }, collections: [users, pages],});defineConfig takes a CMSConfig. Only collections is required.
| Key | Type | Description |
|---|---|---|
collections |
CollectionConfig[] |
The content schema — see Collections |
locales |
{ default, supported } |
Locales for translatable fields — see Internationalization |
admin |
AdminConfig |
Admin UI behaviour: navigation, uploads, rate limiting, auth, webhooks, colors, date display |
images |
ImagesConfig |
Image renditions and the Cloudflare image pipeline |
integrations |
IntegrationsConfig |
Durable task handlers and recurring schedules |
collaboration |
CollaborationConfig |
Editorial review workflow |
locales
Section titled “locales”| Option | Type | Description |
|---|---|---|
default |
string |
Base locale. New documents get this as their _sourceLocale unless overridden |
supported |
string[] |
Every locale editors can translate into; must include default |
Omit locales entirely on a single-language site. See Internationalization and Content language.
| Option | Type | Default | Description |
|---|---|---|---|
nav |
{ label, href, icon?, weight? }[] |
[] |
Extra sidebar links — see Custom navigation |
editBar |
boolean |
true |
“Edit this page” chip on public pages for logged-in editors — see Edit bar |
uploads |
{ allowedTypes?, maxFileSize? } |
images, PDF, video; 50 MB | Upload restrictions — see Uploads |
rateLimit |
{ maxAttempts?, windowMs? } |
5 / 15 min |
Failed-login throttle — see Rate limiting |
auth |
AdminAuthConfig |
local password login | password.enabled, password.forgotPassword, password.emailVerification, provider stubs — see Authentication |
webhooks |
WebhookConfig[] |
[] |
Outbound webhooks on content events — see Webhooks |
colors |
{ label, value }[] |
— | Palette offered by every fields.color() — see Colors |
dateFormat |
string |
"en-US" |
BCP-47 locale for date display — see Date & time |
timeZone |
string |
browser | IANA time zone for date display |
dateTimeFormat |
Intl.DateTimeFormatOptions |
— | Overrides merged over the default date format |
dateTimePattern |
string |
— | Explicit token pattern; wins over dateFormat / dateTimeFormat |
images
Section titled “images”| Option | Type | Default | Description |
|---|---|---|---|
presets |
Record<string, ImagePreset> |
built-ins | Named renditions { aspect?, widths, formats?, sizes? }, merged over the defaults — see Presets |
cloudflare |
"worker" | "cdn-cgi" |
"worker" |
How renditions are produced on Cloudflare — see Image optimization |
integrations
Section titled “integrations”| Option | Type | Description |
|---|---|---|
tasks |
Record<string, (payload, { config }) => …> |
Durable task handlers keyed by task type; inbound webhooks arrive as webhook.<provider> |
schedules |
{ task, payload?, everyMinutes }[] |
Recurring tasks enqueued by the cron tick |
See Background Tasks.
collaboration
Section titled “collaboration”| Option | Type | Default | Description |
|---|---|---|---|
collections |
(string | { slug, requireApproval? })[] |
[] |
Which collections get the review workflow |
requireApproval |
boolean |
false |
Block publishing until a document is approved |
approverRoles |
string[] |
["admin"] |
Roles that can approve, request changes, and bypass the publish gate |
See Collaboration.
Project-owned files
Section titled “Project-owned files”The CMS runtime is split into two kinds of files. Managed directories are the runtime itself — in package mode they ship inside @kidecms/core, in embedded mode they sit in src/cms/ and upgrades patch them for you. Project-owned files are yours in both modes: the scaffolder writes them once, and no upgrade touches them without your review.
src/cms/ cms.config.ts # project-owned collections/ # project-owned adapters/ # project-owned db.ts storage.ts email.ts runtime.ts # project-owned fields/ # project-owned (optional) migrations/ # project-owned (Cloudflare D1 only) seed.ts # project-owned (optional) .generated/ # generated — never edit core/ admin/ routes/ middleware/ client/ platform/ internals/ # managed| File | What it is for |
|---|---|
cms.config.ts |
The defineConfig() call above. Registers collections and holds every top-level option |
collections/ |
One defineCollection() per file — see Collections |
adapters/db.ts |
Selects the database platform. One line: export * from "@kidecms/core/platform/node/database" (or .../platform/cloudflare/database). Exposes getDb() and closeDb() |
adapters/storage.ts |
Selects file storage the same way (platform/node/storage or platform/cloudflare/storage). Exposes putFile, getFile, deleteFile, and an optional getFileStream |
adapters/email.ts |
Outgoing email. Ships a Resend implementation of sendInviteEmail, sendPasswordResetEmail, sendFormSubmissionEmail, and isEmailConfigured. Swap the fetch calls for your provider |
runtime.ts |
The composition root. Calls initSchema() with the generated schema and configureCmsRuntime({ getDb, closeDb, storage, email, env }), then re-exports the runtime API for routes |
fields/ |
Custom admin field components (.tsx, default export). Referenced by file name from admin.component — see Custom field components |
migrations/ |
Drizzle SQL migrations written by pnpm db:generate. Used by Cloudflare D1 only (wrangler d1 migrations apply); the Node target syncs with cms:push and has no migrate-on-boot |
seed.ts |
Optional. Default-exports Record<collectionSlug, document[]>; pnpm cms:seed loads it |
.generated/ |
schema.ts, types.ts, validators.ts, api.ts — regenerated from the config by pnpm cms:generate and on every dev-server boot. Do not edit |
A few files outside src/cms/ are project-owned too and get the same careful treatment on upgrade: astro.config.mjs, drizzle.config.ts, src/env.d.ts, src/styles/admin.css (the admin color tokens), and the render components the runtime reaches through virtual modules — src/components/BlockRenderer.astro, ContentRenderer.astro, and CmsImage.astro.
Adapter contracts
Section titled “Adapter contracts”The adapters are plain modules, imported by runtime.ts and by CMS routes. Replace an implementation by keeping the exports and signatures.
adapters/storage.ts:
export function putFile(storagePath: string, data: ArrayBuffer | Uint8Array): Promise<void>;export function getFile(storagePath: string): Promise<ArrayBuffer | null>;export function deleteFile(storagePath: string): Promise<void>;export function getFileStream(storagePath: string): Promise<{ body: ReadableStream; size: number } | null>; // optionaladapters/email.ts must export all four functions, even if some only return false:
export function sendInviteEmail(to: string, inviteUrl: string): Promise<boolean>;export function sendPasswordResetEmail(to: string, resetUrl: string): Promise<boolean>;export function sendFormSubmissionEmail(to: string, formTitle: string, data: Record<string, unknown>): Promise<boolean>;export function isEmailConfigured(): boolean;storagePath is the /uploads/<id>.<ext> string stored in image fields. Email functions return false (rather than throwing) when delivery is not configured; for invites the admin then shows a copyable link instead.
Inside adapters, read environment variables with readEnv() from @kidecms/core, not import.meta.env — the latter is inlined at build time and cannot see runtime secrets on Cloudflare.