Content Modeling
Krios is schema-first. Content types are the schema; entries are instances; fields belong to types and inherit. This page covers the engineering surface — see the linked sub-pages for type-by-type detail.
Vocabulary
- Content type — the shape of a kind of entry. Has an
apiName(camelCase, used by APIs and codegen),name(display label), flags (isRoutable,isPublishable,isSingleton), an icon, and a list of fields. - Field — one named slot on a content type. Has an
apiName,fieldType, flags (isRequired,isLocalizable,isMultiple), optional validations, and editor-only UI hints (tab,helpText). - Entry — one row of a content type. Field values are stored per locale in
ContentFieldValue; non-localizable fields use the synthetic__sharedlocale.
Schema relationships
ContentType ──────┐
├─ parentId ────┘ (self-relation, max depth 2)
├─ allowedChildTypes[]
├─ availableSiteIds[]
└─ fields[] (FieldDefinition rows)
FieldDefinition
├─ contentTypeId
├─ fieldType (string)
├─ validations / enumValues / allowedTypeIds (Json + arrays)
├─ richTextConfig / linkConfig (Json)
├─ defaultValue (Json)
└─ uiConfig (Json — { tab?, helpText? })
uiConfig on the content type carries { tabOrder?: string[] }.
Validation pipeline
Save-time:
validateFieldValuechecks shape + per-type constraints (regex, min/max, enumOptions membership, allowedTypeIds for refs, allowedAssets for media, link config).- Required-field gate runs at publish time, not save — drafts can be incomplete.
assertReadyToPublishwalks references and rejects publish if a required reference is still draft.
The CLI's krios schema diff re-runs the full validator against local schema files vs the project's current state.
Stale references
When a referenced content type is deleted, sanitizeContentTypeReferences strips the dangling id from allowedChildTypes and from field-level allowedTypeIds / linkConfig.allowedInternalTypeIds on read. Editors can open and re-save the affected types to clean up the stored values.
Sub-pages
- Content types — the type-level schema
- Field types — the eleven built-in field types + custom types
- Rich text — the AST, marks, embedded content
- Blocks and composition — building landing pages from blocks
- Inheritance — single inheritance, max depth 2
- Best practices — naming, composition, tabs