Dyrected
Model ContentFields

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 the renameTo fallback.
  • label — the human-readable name shown to editors. Defaults to a title-cased name.
  • required — whether the field must have a value. A missing value fails validation with a 400.
  • unique — enforces a database uniqueness constraint. A duplicate write fails with a 409.
  • 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-field read and update rules 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:

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;
}
OptionDescription
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;
}
OptionDescription
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;
}
OptionDescription
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;
}
OptionDescription
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;
}
OptionDescription
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;
}
OptionDescription
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;
}
OptionDescription
maxWords (optional)Advisory maximum word count exposed to editors and client tooling.

On this page

Dyrected| Cloud

Get your backend ready in minutes

Use a managed database, storage, APIs, and admin dashboard without setting up the infrastructure yourself.

Set Up My Backend