Fields API
Companions:
- Fields — recipes and explanation for schema helpers, admin helpers, component slots, conditions, and cross-field writes.
- Collections API — the collection and block definitions that contain field arrays.
- Relationships — relation envelopes, population, filters, and
hasManybehavior. - File and media uploads —
UploadConfig, stored file values, storage routing, variants, and upload hooks. - Rich text — Lexical
EditorConfig, extensions, relation modes, and server adapters.
This reference lists every field kind accepted by CollectionDefinition.fields and Block.fields. A field is a discriminated object whose type selects its value shape and type-specific options.
Common field properties
Every field accepts these properties in addition to its required name and type.
Property | Default | Description |
| Required | Stable field key. It participates in schema paths, generated types, storage paths, and API values. Reserved system names are rejected. |
| Required | One of the 22 field discriminators listed below. |
| Derived by the UI | Human-readable admin label. |
| None | Supporting text rendered with the input. |
| None | Placeholder hint forwarded by widgets that support it. |
|
| Makes the generated property optional and permits an absent value. Fields are required by default. |
|
| Admin rendering hint. It is not server-side immutability or an authorization boundary. |
| None | Client-side |
| None | Client-side visibility predicate over the full form data and current sibling scope. Hidden values remain stored. |
|
| Makes the value available to form state and lifecycle hooks but excludes it from persistence. |
| None | Submit-time validator |
|
| Available only on localizable field kinds. Stores a distinct value per content locale when |
optional
An optional field becomes an optional property in inferred and generated object types. The value type also permits undefined.
{ name: 'subtitle', type: 'text', optional: true }// Inferred shape: subtitle?: string | undefinedreadOnly
readOnly prevents normal editing in widgets that implement the hint. API clients can still submit the field. Enforce security and immutability in abilities, hooks, lifecycle services, or a field-specific server rule.
condition
type FieldCondition = ( data: Record<string, any>, siblingData: Record<string, any>) => booleanThe admin re-evaluates the condition as form data changes. Hidden fields retain their values and are exempt from client validation while hidden. A conditionally hidden required field should normally be optional or have a default.
{ name: 'thumbnailCaption', type: 'text', optional: true, condition: (_data, siblings) => Boolean(siblings.generateThumbnail),}virtual
A virtual value reaches beforeCreate, afterCreate, beforeUpdate, and afterUpdate, but the storage flatten pass writes no row for it. It is absent on the next read.
Boot validation enforces these constraints:
- it must be optional or declare a
defaultValue; - it cannot be a
counter; - an upload-capable
fileorimagecannot be virtual; and useAsTitle,useAsPath, and search configuration cannot reference it.
Setting virtual on group, array, or blocks omits the entire subtree.
Field kind index
Byline has three structure fields and 19 value fields.
| Value shape | Localizable | Type-specific properties |
| Object from nested fields | No |
|
| Ordered array of | No |
|
| Ordered discriminated block array | No |
|
|
| Yes |
|
|
| Yes |
|
|
| Yes |
|
|
| No |
|
|
| No |
|
| Declared option-value union | No |
|
| JSON value | Yes |
|
|
| No |
|
|
| No |
|
|
| No |
|
|
| No |
|
|
| No |
|
|
| No |
|
|
| No |
|
| JSON value | Yes |
|
| JSON object | Yes |
|
| Relation envelope or ordered envelope array | No |
|
|
| No |
|
|
| No |
|
Array and block _id values are synthetic identity metadata. They stabilize editing and ordering but are not user schema data.
Structure fields
group
interface GroupField { name: string type: 'group' fields: readonly Field[]}Groups assemble nested fields into one object without creating a repeated item boundary.
{ name: 'seo', type: 'group', fields: [ { name: 'title', type: 'text', optional: true }, { name: 'description', type: 'textArea', optional: true }, ],}array
interface ArrayField { name: string type: 'array' fields: readonly Field[] validation?: { minLength?: number; maxLength?: number }}Each stored item gains a synthetic _id. Array values preserve order.
{ name: 'authors', type: 'array', validation: { minLength: 1, maxLength: 10 }, fields: [ { name: 'name', type: 'text' }, { name: 'role', type: 'text', optional: true }, ],}blocks
interface BlocksField { name: string type: 'blocks' blocks: Block[]}Each block value contains synthetic _id identity and a _type discriminator equal to the definition's blockType.
{ name: 'content', type: 'blocks', blocks: [RichTextBlock, PhotoBlock, QuoteBlock],}Text fields
text and textArea
interface TextFieldOptions { defaultValue?: DefaultValue<string> validation?: { minLength?: number maxLength?: number pattern?: string rules?: ValidationRule[] }}Both store strings and support localization. They differ in their default admin widget.
code
interface CodeFieldOptions { defaultValue?: DefaultValue<string> language?: string languageField?: string validation?: { minLength?: number maxLength?: number rules?: ValidationRule[] }}language sets the default syntax-highlighting language. languageField names a sibling string field whose live value overrides it. Both affect presentation only; storage contains the source string.
Choice fields
checkbox and boolean
Both store boolean and accept defaultValue?: DefaultValue<boolean>. They remain separate discriminators so admin widgets and semantics can differ.
select
interface SelectFieldOption { label: string value: string}
interface SelectField { type: 'select' options: [SelectFieldOption, ...SelectFieldOption[]] defaultValue?: DefaultValue<string>}The options array must be non-empty. defineCollection() preserves literal values so generated types become their union.
{ name: 'format', type: 'select', options: [ { label: 'Article', value: 'article' }, { label: 'Report', value: 'report' }, ], defaultValue: 'article',}Rich text
interface RichTextFieldOptions { defaultValue?: DefaultValue<unknown> validation?: { minLength?: number; maxLength?: number } editorConfig?: unknown embedRelationsOnSave?: boolean populateRelationsOnRead?: boolean}Property | Default | Description |
| Adapter defaults | Serializable editor-specific data. For Lexical this is |
|
| Refreshes relation-bearing nodes during writes through the registered server embed adapter. |
| Inverse of | Refreshes relation-bearing nodes during reads through the registered server populate adapter. |
At least one relation mode must be effective. Setting both flags to false fails boot validation. Setting both to true embeds on write and refreshes on read.
Rich text documents Lexical configuration, extensions, markdown, toolbar contributions, and server adapters.
Date, time, and numeric fields
time
Stores a time string and accepts defaultValue?: DefaultValue<string>.
date
Uses a Date value and accepts defaultValue?: DefaultValue<Date>.
datetime
interface DateTimeFieldOptions { mode?: 'date' | 'datetime' yearsInFuture?: number yearsInPast?: number defaultValue?: DefaultValue<Date>}mode controls the admin input mode. The year-range values bound the date picker.
float and integer
interface NumericFieldOptions { defaultValue?: DefaultValue<number> validation?: { min?: number; max?: number }}Both restore as JavaScript number; integer uses integer storage and validation semantics.
decimal
Decimal values are precision-preserving strings, not JavaScript numbers.
{ name: 'price', type: 'decimal', defaultValue: '0.00' }Allocated and JSON fields
counter
interface CounterField { type: 'counter' group: string}The lifecycle allocates an immutable monotonically increasing integer at create time. Counter fields sharing the same stable group share one sequence across collections. Gaps can occur after rollbacks and deletes. A counter has no default or validation slot and cannot appear inside arrays or blocks.
json
Stores any JSON value and supports localization.
type JsonValue = string | number | boolean | null | JsonValue[] | JsonObjectobject
Stores a JSON object and supports localization.
type JsonObject = { [key: string]: JsonValue }Relations
interface RelationField { type: 'relation' targetCollection: string displayField?: string hasMany?: boolean minItems?: number maxItems?: number}Property | Default | Description |
| Required | Target collection path. |
| Target identity fallback | Target field displayed in the picker and inline summary. |
|
| Changes the value from one envelope to an ordered array of envelopes. |
| None | Minimum array length when |
| None | Maximum array length when |
The canonical unpopulated value is RelatedDocumentValue; population adds a target ClientDocument under .document. Relationships documents all envelope states and the populate DSL.
File and image fields
interface FileField { type: 'file' upload?: UploadConfig}
interface ImageField { type: 'image' upload?: UploadConfig}Both restore a StoredFileValue. Adding upload makes that field upload-capable and mounts it on the collection upload transport. Image processing depends on MIME type and configured sizes, not on whether the discriminator is file or image.
The complete UploadConfig, ImageSize, storage precedence, hook, transport, and stored-value contracts are in File and media uploads.
Default values
Value fields that expose defaultValue accept a literal or a synchronous/async factory:
type DefaultValue<T> = | T | ((ctx: { data: Record<string, any> locale?: string now: () => Date uuid?: () => string }) => T | Promise<T>){ name: 'publishedOn', type: 'datetime', defaultValue: ({ now }) => now(),}Validation
validation
Type-specific validation objects provide declarative length, range, pattern, or rule checks. Supported generic rules are:
interface ValidationRule { type: 'min' | 'max' | 'pattern' | 'custom' | 'email' | 'url' value: any message?: string}validate
Every field also accepts a submit-time function:
validate?: (value: any, data: Record<string, any>) => string | undefinedReturn a non-empty string to block submission and display the field error.
Field hooks
interface FieldHooks { beforeValidate?: FieldBeforeValidateFn | FieldBeforeValidateFn[] beforeChange?: FieldBeforeChangeFn | FieldBeforeChangeFn[]}Both receive the changing value, previous value, full form data, instance path, field definition, operation (change or submit), and setFieldValue(path, value).
Hook | Effect |
| Runs before built-in validation. Returning |
| Runs before the form write. Returning |
setFieldValue() writes another field and emits its patch without running the target field's hooks, preventing hook recursion.
Admin field overrides
interface FieldAdminConfig { components?: { Label?: SlotComponent<FieldLabelSlotProps> HelpText?: SlotComponent<FieldHelpTextSlotProps> Field?: SlotComponent<FieldInputSlotProps> beforeField?: SlotComponent<FieldAdornmentSlotProps> afterField?: SlotComponent<FieldAdornmentSlotProps> } editor?: RichTextEditorComponent}Property | Description |
| Replaces the default label. |
| Replaces the default help text. |
| Replaces the complete value-field input and must call |
| Renders between label and input. |
| Renders between input and help text. |
| Replaces the React editor for this rich-text field only. Ignored for other field types. |
Collection overrides are keyed by index-free schema path in CollectionAdminConfig.fields. Block overrides are keyed relative to the block root in BlockAdminConfig.fields.
Field helper and inference functions
Symbol | Purpose |
| Identity helper that preserves one field's literal type information. |
| Infers a collection's ordinary single-locale field object. |
| Infers its all-locales field object. |
| Infers one block's ordinary field object. |
| Infers one block's all-locales field object. |
| Narrows to |
| Narrows to |
| Narrows to |
| Narrows to |
| Narrows to the 19 value-field kinds. |