Overview
Fields define the shape of every document. Learn the shared field model before reaching for a specific type.
Fields are how you describe the shape of a document in Dyrected. Every collection and global has a fields array, and each entry defines one piece of content: its name, its type, its label, and any type-specific options.
You will spend most of your modeling time here, so it helps to learn the shared model once and then reach for the specific field pages when you need them.
The shared field shape
Every field is an object with at least a type. Named fields also carry a name that becomes the stored key, and a label that editors see in the admin UI.
import { defineCollection, defineTextField, defineRichTextField, defineRelationshipField } from '@dyrected/core'
export const Posts = defineCollection({
slug: 'posts',
fields: [
defineTextField({ name: 'title', label: 'Title', required: true }),
defineRichTextField({ name: 'body', label: 'Body' }),
defineRelationshipField({ name: 'author', label: 'Author', relationTo: 'users' }),
],
})Give every named field an explicit label. It keeps internal camelCase names out of the editing interface and makes the admin UI feel deliberate.
Shared options you will use everywhere
Most field types accept a common set of base options:
name— the persisted key. A rename is a data migration, so plan it with database migrations or therenameTofallback.label— the human-readable name shown to editors. Defaults to a title-casedname.required— whether the field must have a value. A missing value fails validation with a400.unique— enforces a database uniqueness constraint. A duplicate write fails with a409.defaultValue— the value used when a new document omits the field. It is evaluated on the server.promoted— pulls the field out of the JSON document into its own indexed column so you can filter and sort on it quickly. See Database indexes.access— per-fieldreadandupdaterules that hide or lock the field for some users. See Field access control.admin— per-field admin options such as descriptions, placeholders, and conditional display.
Some field types add a few more admin-only options of their own. For example, nested array and object fields can use admin.useAsTitle for compact summaries, and join fields can use admin.showCreateButton / admin.showViewButton to control their helper actions.
Choosing a field type
Each field type has its own page with a focused example and its generated contract:
- Text-like content: Text, Textarea, Email, URL, Icon, Rich Text
- Choices and toggles: Select, Multi Select, Radio, Boolean
- Numbers and dates: Number, Date, Datetime, Time
- Structure and nesting: Object, Array, Blocks, Row
- Relationships and files: Relationship, Image, Join
- Data and layout: JSON
Generated reference
The contracts below are generated from the public @dyrected/core exports by @dyrected/knowledge. This region holds the shared field interfaces and admin option types; the contract for each concrete field type lives on that type's own page.
AuthDocFields
Exported type from @dyrected/core.
export type AuthDocFields = {
email: string;
password?: string;
roles?: string[];
};BaseFieldAdmin
Exported interface from @dyrected/core.
export interface BaseFieldAdmin {
/** Placeholder text shown when the input has no value. */
placeholder?: string;
/** For nested object-like fields, choose which child field should summarize the value in admin surfaces. */
useAsTitle?: string;
/** Custom component key registered in the Admin UI. */
component?: string;
/** Help text rendered below the field. */
description?: string;
/** Hides the field from the Admin form without deleting stored data. */
hidden?: boolean;
/** Excludes the field from Admin list filtering. */
filterable?: boolean;
/** Renders the field as non-editable in the Admin UI. */
readOnly?: boolean;
/** Hides the field's label in the Admin form (e.g. single-field array rows where the label is redundant). */
hideLabel?: boolean;
/** Reactive condition controlling whether the field is visible in the Admin UI. */
condition?:
| ((
data: Record<string, unknown>,
siblingData: Record<string, unknown>,
) => boolean)
| string;
/** Tab name used when the edit form is rendered as tabs. */
tab?: string;
/** CSS width hint used when the field appears inside a `row`. */
width?: string;
}| Option | Description |
|---|---|
placeholder (optional) | Placeholder text shown when the input has no value. |
useAsTitle (optional) | For nested object-like fields, choose which child field should summarize the value in admin surfaces. |
component (optional) | Custom component key registered in the Admin UI. |
description (optional) | Help text rendered below the field. |
hidden (optional) | Hides the field from the Admin form without deleting stored data. |
filterable (optional) | Excludes the field from Admin list filtering. |
readOnly (optional) | Renders the field as non-editable in the Admin UI. |
hideLabel (optional) | Hides the field's label in the Admin form (e.g. single-field array rows where the label is redundant). |
condition (optional) | Reactive condition controlling whether the field is visible in the Admin UI. |
tab (optional) | Tab name used when the edit form is rendered as tabs. |
width (optional) | CSS width hint used when the field appears inside a `row`. |
CharacterLimitFieldAdmin
Exported type from @dyrected/core.
export type CharacterLimitFieldAdmin = {
/** Admin-only compatibility alias for `field.maxLength`. Prefer the top-level field property. */
maxLength?: number;
};CharacterLimitFieldConfig
Exported interface from @dyrected/core.
export interface CharacterLimitFieldConfig {
/** Advisory maximum character count exposed to editors and client tooling. */
maxLength?: number;
}| Option | Description |
|---|---|
maxLength (optional) | Advisory maximum character count exposed to editors and client tooling. |
DynamicOptionItem
Exported type from @dyrected/core.
export type DynamicOptionItem = string | { label: string; value: unknown };DynamicOptionsConfig
Exported interface from @dyrected/core.
export interface DynamicOptionsConfig {
/** Resolver function executed on the server to produce option items. */
resolve: DynamicOptionsResolver;
/** Cache duration in seconds for identical resolver calls. */
cacheTTL?: number;
}| Option | Description |
|---|---|
resolve (required) | Resolver function executed on the server to produce option items. |
cacheTTL (optional) | Cache duration in seconds for identical resolver calls. |
DynamicOptionsResolver
Exported type from @dyrected/core.
export type DynamicOptionsResolver = (
args: DynamicOptionsResolverArgs,
) => Promise<DynamicOptionItem[]> | DynamicOptionItem[];DynamicOptionsResolverArgs
Exported interface from @dyrected/core.
export interface DynamicOptionsResolverArgs {
/** Database adapter available to server-side option resolvers. */
db?: DatabaseAdapter;
/** Authenticated user making the request, if any. */
user?: AuthenticatedUser;
/** Current HTTP request context, including query parameters. */
req: HookRequestContext;
}| Option | Description |
|---|---|
db (optional) | Database adapter available to server-side option resolvers. |
user (optional) | Authenticated user making the request, if any. |
req (required) | Current HTTP request context, including query parameters. |
Field
Exported type from @dyrected/core.
export type Field =
| TextField
| TextareaField
| EmailField
| UrlField
| IconField
| DateField
| DateTimeField
| TimeField
| SelectField
| RadioField
| NumberField
| BooleanField
| MultiSelectField
| RelationshipField
| ImageField
| RichTextField
| JsonField
| ObjectField
| ArrayField
| BlocksField
| JoinField
| RowField;FieldBase
Exported interface from @dyrected/core.
export interface FieldBase {
/** Stored key for this field. Omit only for layout-only fields such as `row` or `join`. */
name?: string;
/** Human-readable label shown in the Admin UI. */
label?: string;
/** Whether the field must have a value when saving. */
required?: boolean;
/** Whether values for this field must be unique across the collection. */
unique?: boolean;
/** Default value used when a new document omits this field. */
defaultValue?: unknown;
/** Static or dynamic option source for supported selection fields. */
options?:
| string[]
| { label: string; value: unknown }[]
| DynamicOptionsResolver
| DynamicOptionsConfig;
/** Target collection slug for `relationship` fields. */
relationTo?: string;
/** Whether the field stores multiple values instead of one. */
hasMany?: boolean;
/** Child fields for `object` and `array` field types. */
fields?: Field[];
/** Allowed block definitions for a `blocks` field. */
blocks?: Block[];
/**
* Shared block slugs pulled from the root `defineConfig({ blocks: [...] })`
* registry for a `blocks` field.
*
* Use this when the same block types should be reused across multiple fields
* without inlining the full block schema into each field definition.
*/
blockReferences?: string[];
/** Target collection slug for `join` fields. */
collection?: string;
/** Back-reference field name on the joined collection. */
on?: string;
/** Maximum number of joined documents returned by a `join` field. */
limit?: number;
/** Field-level read, create, and update access rules. Supports functions, Jexl strings, booleans, and named policies. */
access?: {
/** Controls whether this field is returned in API responses. */
read?: AccessRule;
/** Controls whether this field may be set when creating a document. Falls back to `update` when omitted. */
create?: AccessRule;
/** Controls whether incoming writes may change this field on update. */
update?: AccessRule;
};
/** Admin-only presentation options for this field. */
admin?: BaseFieldAdmin;
/** Previous storage key this field falls back to. When the field has no value, its value is read from the old key at read time, then rewritten under the new key on the next save. */
renameTo?: string;
/** Whether SQL adapters should promote this field into a first-class column. */
promoted?: boolean;
}| Option | Description |
|---|---|
name (optional) | Stored key for this field. Omit only for layout-only fields such as `row` or `join`. |
label (optional) | Human-readable label shown in the Admin UI. |
required (optional) | Whether the field must have a value when saving. |
unique (optional) | Whether values for this field must be unique across the collection. |
defaultValue (optional) | Default value used when a new document omits this field. |
options (optional) | Static or dynamic option source for supported selection fields. |
relationTo (optional) | Target collection slug for `relationship` fields. |
hasMany (optional) | Whether the field stores multiple values instead of one. |
fields (optional) | Child fields for `object` and `array` field types. |
blocks (optional) | Allowed block definitions for a `blocks` field. |
blockReferences (optional) | Shared block slugs pulled from the root `defineConfig({ blocks: [...] })` registry for a `blocks` field. Use this when the same block types should be reused across multiple fields without inlining the full block schema into each field definition. |
collection (optional) | Target collection slug for `join` fields. |
on (optional) | Back-reference field name on the joined collection. |
limit (optional) | Maximum number of joined documents returned by a `join` field. |
access (optional) | Field-level read, create, and update access rules. Supports functions, Jexl strings, booleans, and named policies. |
admin (optional) | Admin-only presentation options for this field. |
renameTo (optional) | Previous storage key this field falls back to. When the field has no value, its value is read from the old key at read time, then rewritten under the new key on the next save. |
promoted (optional) | Whether SQL adapters should promote this field into a first-class column. |
FieldType
Exported type from @dyrected/core.
export type FieldType =
| "text"
| "textarea"
| "richText"
| "number"
| "boolean"
| "date"
| "datetime"
| "time"
| "select"
| "multiSelect"
| "radio"
| "relationship"
| "array"
| "object"
| "json"
| "blocks"
| "image"
| "email"
| "url"
| "icon"
| "join"
| "row";InferDocShape
Exported type from @dyrected/core.
export type InferDocShape<Fields extends readonly Field[]> = Fields extends readonly []
? Record<never, never>
: Fields extends readonly [infer Head extends Field, ...infer Tail extends readonly Field[]]
? InferFieldEntry<Head> & InferDocShape<Tail>
: Record<string, unknown>;NumberLimitFieldAdmin
Exported type from @dyrected/core.
export type NumberLimitFieldAdmin = {
/** Admin-only compatibility alias for `field.min`. Prefer the top-level field property. */
min?: number;
/** Admin-only compatibility alias for `field.max`. Prefer the top-level field property. */
max?: number;
};NumberLimitFieldConfig
Exported interface from @dyrected/core.
export interface NumberLimitFieldConfig {
/** Advisory minimum numeric value exposed to editors and client tooling. */
min?: number;
/** Advisory maximum numeric value exposed to editors and client tooling. */
max?: number;
}| Option | Description |
|---|---|
min (optional) | Advisory minimum numeric value exposed to editors and client tooling. |
max (optional) | Advisory maximum numeric value exposed to editors and client tooling. |
SystemDocFields
Exported type from @dyrected/core.
export type SystemDocFields = {
createdAt?: string;
updatedAt?: string;
createdBy?: string;
updatedBy?: string;
};TypedField
Exported type from @dyrected/core.
export type TypedField<
TType extends FieldType,
TValue,
TAdminExtra = Record<never, never>,
> = Omit<FieldBase, "admin"> & {
type: TType;
admin?: BaseFieldAdmin & TAdminExtra;
} & FieldHooks<TValue> &
FieldAdminHooks<TValue>;UploadDocFields
Exported type from @dyrected/core.
export type UploadDocFields = {
filename: string;
filesize?: number;
mimeType: string;
url: string;
width?: number;
height?: number;
focalPoint?: { x: number; y: number };
blurhash?: string;
sizes?: Record<string, { filename?: string; url?: string; width?: number; height?: number }>;
};WordLimitFieldAdmin
Exported type from @dyrected/core.
export type WordLimitFieldAdmin = {
/** Admin-only compatibility alias for `field.maxWords`. Prefer the top-level field property. */
maxWords?: number;
};WordLimitFieldConfig
Exported interface from @dyrected/core.
export interface WordLimitFieldConfig {
/** Advisory maximum word count exposed to editors and client tooling. */
maxWords?: number;
}| Option | Description |
|---|---|
maxWords (optional) | Advisory maximum word count exposed to editors and client tooling. |