Skip to main content
Fields define the shape of Documents stored in a Collection. FrogBot uses the same definitions to build database schemas, API responses, generated TypeScript types, and the editing interface in the admin panel. Most fields store data. Layout fields organize the editing interface without adding values to a Document, while virtual fields expose values that are not persisted.
FrogBot also contributes fields to collections with framework roles. See role-marked collections and Default Fields.

Field types

Choose the field type that matches the value and editing experience you need.

Data fields

Data fields have a name and ordinarily store their value in the database.
  • Array for repeating rows of nested fields
  • Blocks for block-based content
  • Checkbox for boolean values
  • Code for source code stored as a string
  • Date for date and time values
  • Email for validated email addresses
  • Group for fields nested in a keyed object
  • JSON for structured JSON values
  • Number for numeric values
  • Point for geographic coordinates
  • Radio for one value from a visible set of choices
  • Relationship for references to other collections
  • Rich Text for structured rich content
  • Select for one or more values from a choice list
  • Tabs for named groups displayed as tabs
  • Text for single-line strings
  • Textarea for multi-line strings
  • Upload for references to file collections

Layout fields

Layout fields organize the admin form and do not store their own value.
  • Collapsible groups fields in an expandable section.
  • Row arranges fields horizontally.
  • Unnamed Groups and unnamed Tabs arrange nested fields without adding another key to the Document.
  • UI renders a custom interface without storing data.

Virtual fields

Join fields are virtual by design. Other data fields can use virtual: true and an afterRead hook to return a computed value without persisting it.
If no built-in field type fits your application, combine validation with a custom field component to create the required editing experience while keeping an appropriate underlying data type.

Virtual field configuration

Any data field can be made virtual by setting its virtual property. Virtual values appear in API responses and can be displayed in the admin panel, but FrogBot does not persist them in the database. They are useful for computed values, relationship summaries, and formatted versions of stored data. The virtual property accepts either true or a string relationship path.

Boolean virtual fields

Setting virtual: true marks the field as virtual but does not populate it. Use an afterRead field hook to calculate its value.

String path virtual fields

A string virtual value creates a virtual relationship field. FrogBot follows the path from a relationship in the current Document and returns the value at the destination.

Display in the admin

In List, Board and Calendar, a string path virtual field shows its value the way the field at the end of the path shows it. A path to a money field shows a money amount, a path to a select or radio with option colors shows the coloured pill, and a path to a date uses that date field’s display format. An empty value shows what the source field shows when it is empty, so an empty money amount shows nothing, and 0 shows as zero ($0.00).
A task whose project has a budget of 12.5 shows $12.50 in the Project Budget column, and a task tagged “urgent” and “backend” shows urgent, backend.
  • Sources. The field at the end of the path can be a text, textarea, email, number, select, radio, checkbox or date field, including fields built on them such as money. The path can cross several relationships, named groups and named tabs.
  • Lists. When the path crosses a hasMany relationship, each non-empty value is shown with the source field’s display, separated by commas. In the List, only the first value links to the Document.
  • Type and options. Give the virtual field the source field’s type, options and hasMany. The display follows the source field, but filters and generated types follow what you write on the virtual field.
  • Paths that can’t be followed. If the path names a field that doesn’t exist, passes through an array or blocks field, crosses a relationship to more than one collection, or ends at an unsupported or virtual field, the field shows as a plain value. A misspelt path returns an empty value and doesn’t stop FrogBot from starting.
  • Your own display. A custom Cell on the virtual field, or a field factory such as moneyField() used for the virtual field itself, is used instead of the source field’s display.
  • Edit view. The edit view shows the virtual field’s own read-only input for the type you wrote. For example, a number virtual field pointing at a money field shows 12.5.
Grouping a Board by a virtual path field, or using one as a Calendar date, isn’t supported.

Virtual path syntax

Virtual paths use dot notation to traverse relationships and nested data:
  • author.name returns the name field from the author relationship.
  • author.profile.bio returns bio from the related author’s nested profile object.
  • categories.title returns the title values from a hasMany relationship.
  • request.additionalStakeholders.email traverses multiple relationship levels.
The first path segment must name a relationship field in the same collection. Paths resolve while FrogBot reads the Document. When a path traverses a hasMany relationship, the virtual field returns an array of values.

Common use cases

Displaying relationship names

Add a virtual field when an API response should expose a useful property next to a relationship ID:

Multiple relationship values

Virtual paths through hasMany relationships return arrays:

Computed values

Use a hook when the result is calculated rather than read from a relationship:

Virtual fields in API responses

Virtual fields appear alongside stored fields in API responses:
A string virtual path cannot resolve unless its source relationship exists in the same collection. For example, virtual: 'author.name' requires an author relationship field.

Field options

Every field requires a type. Data fields also require a name. Each field type adds options for its value, storage, validation, and editing interface.
See the page for each field type for its complete options.
A field is an object with at least a type. The selected type determines the other accepted options, API value shape, and default admin component.

Field names

Field names become keys in API response objects and generated TypeScript types. Names must be unique among sibling fields. Use JavaScript-style identifiers that begin with a letter or underscore and contain only letters, numbers, and underscores.
Avoid names beginning with a digit, such as 1field, or containing hyphens, such as field-name. Although these are valid string values, they can conflict with dot-notation paths, database columns, and schema identifiers.
FrogBot reserves internal names. A reserved field is removed while the configuration is sanitized. The following names cannot be used:
  • __v
  • salt
  • hash
  • file
  • status when drafts and the Postgres adapter are enabled
Enabled FrogBot features can reserve additional names for the fields they manage. See Default Fields for those conditional fields.

Field-level hooks

Field hooks run at specific points while FrogBot creates, updates, or reads a Document.
Hook arguments include a FrogBotRequest. Server hooks access the current framework instance through req.frogbot, not through a separate global or per-field instance.
See Field Hooks for hook order and all arguments.

Field-level access control

Field access functions control whether a field can be created, updated, or read. They return a boolean and receive the current req, Document data, and sibling data.
See Field Access Control for the operation-specific rules.

Default values

Use defaultValue to populate a missing value during create or update operations and when the Admin Panel opens a create form. It can be a static value or a function based on the current locale or authenticated user.
A default-value function receives:
Static defaults may also be reflected in the database schema by the configured database adapter. Defaults do not replace validation or access control.
A default-value function can use req.frogbot to call the Local API on the server. Keep the function deterministic enough for every create or update path that can omit the field.

Validation

FrogBot automatically validates field types and constraints such as required, min, max, and length limits. Set validate to replace a field’s default validator with application-specific logic.
A validator returns true when the value is valid or an error-message string when it is invalid. It may also return a promise. The context includes:

Validation context

Use the context to compare sibling values, inspect the operation, identify the current Document, or read the authenticated user from req.user. The context also includes the field’s own settings as top-level properties, such as minLength on a Text field or max on a Number field. These settings are typed for that field type and exclude hooks, access, and validate. operation can be any of the four operations or undefined, so a validator that switches on it should handle read and delete too.

Localized error messages

Validation can use the request translation function to return a localized built-in message:
You can also return application-specific translated strings configured through internationalization.

Replacing default field validation

When a field defines validate, FrogBot uses that function instead of the field type’s default validator. FrogBot does not expose the built-in validators through a supported public helper import. Include every type, required, length, range, or format rule that the replacement must retain.

Validation performance

The admin panel runs validation whenever a field changes. Keep synchronous and onChange checks lightweight. For expensive work such as a remote lookup, use event to defer it until form submission.
Validation also runs in the browser for admin form feedback. Browser validation receives form context, but it is not a server-instance API: do not use req.frogbot for client-side database work. Enforce authoritative rules on the server and use hooks or access control when the check requires framework operations.
Validation messages are returned by API operations as well as displayed in the admin panel. Write them so they explain how to correct the value.

Role-marked collections

FrogBot can merge managed fields into a collection marked with chat: true, message: true, file: true, or usageLog: true. A collection can have only one of these role markers, and only one collection can fill each role.
FrogBot preserves compatible authored fields, appends missing role fields, and combines hooks. Incompatible definitions and reserved role fields fail configuration instead of being silently replaced. See Collection Configs for each role’s contribution.

Admin options

Use a field’s admin property to control its presentation without changing API behavior.
Every data field accepts these options. Each field type’s page lists the extra options it adds and any of these it doesn’t support.

Field descriptions

Descriptions give editors instructions or context near a field. Their exact placement depends on the field type. A description can be a string, a server-side function that returns a string, or a custom React component.
To replace the description with a custom component, set admin.components.Description instead. See Description components.

Description functions

Description functions run on the server and are useful for simple localized text. They receive t, the translation function used by the admin panel, and the i18n object.
A description function is not reactive to live form changes. Use a client Description component when the content must subscribe to form state.

Conditional logic

An admin.condition function receives the full form data, sibling data, and context about the field’s location and current user. Return true to display the field. The context object contains:
Conditions affect only the editing interface. Use field access control to protect data returned from or written through APIs.

Custom components

Fields are represented in several places in the admin panel: the form field in an Edit view, a table cell and filter in a List view, and a diff when comparing versions. Set admin.components to replace any of these surfaces or one of the smaller field slots. Component paths are resolved through FrogBot’s import map.
The following component options are available: Layout fields support a subset: Row fields, Tabs fields, and individual tabs have only Field, Cell, Filter, Description, and Diff; Group and Collapsible fields have no Error slot; and UI fields are described on the UI field page. Array fields add RowLabel.

Field

The Field component is the form control editors interact with in an Edit view. Replace it with admin.components.Field:
You do not have to replace the entire Field component. Use Label, Description, Error, beforeInput, or afterInput to customize one part while preserving the default form control.

Default props

Exact props vary by field family, so type your component with that family’s exported prop or component type. Client field components receive: Some families add props, such as inputRef and onKeyDown on Text fields. Server field components receive the same path, schemaPath, readOnly, permissions, forceRender, and renderedBlocks props, plus: FrogBot’s server prop types expose req.frogbot and do not expose a separate top-level framework instance.

Sending and receiving form values

Client components manage form state with hooks and field primitives from @frogbotai/ui/admin. Import the corresponding component type from frogbot.
Client field components receive serializable field and form props. They do not receive a server request or FrogBot instance.

Server field components

Server component types follow the same field-specific naming convention. For example, TextFieldServerProps and TextFieldServerProps are exported from frogbot. Their framework-issued req is a FrogBotRequest, and req.frogbot is attached before the component renders, including form-state rebuilds.
Do not construct this request yourself or use a fallback instance lookup. Components that genuinely have no request prop can import the app config and call getFrogBot({ config }) when they need server access.

Field component types

Each field family exports the props its components receive from frogbot: *FieldClientProps and *FieldServerProps, plus *FieldLabel*Props, *FieldDescription*Props, *FieldError*Props and *FieldDiff*Props. Type a component by its props, as in ({ field }: TextFieldServerProps) => …. UI fields do not have label, description, or error props; Blocks fields additionally provide BlockRowLabelServerProps and BlockRowLabelClientProps.
See the individual field-type pages for the exact types supported by each family.

Cell

The Cell component renders a field’s value in a List view table. Replace it with admin.components.Cell:
A custom Cell appears only in the List view; Board cards and Calendar events show FrogBot’s built-in display for the field. To draw a field the same way in a custom Board Card or Calendar Event, render FieldCell from @frogbotai/ui/admin with the Cell props below. Cells use the generic DefaultCellComponentProps or DefaultServerCellComponentProps types from frogbot. Cell components do not receive field-component form props or a request.
Use DefaultCellComponentProps for a client component with 'use client', and DefaultServerCellComponentProps for a server component. They preserve different default generic types.
Cell props include: Server cells additionally receive collectionConfig, the sanitized collection configuration, and i18n, the admin internationalization object.
Cell components are optimized for table rendering. They do not receive Field component props such as preferences, validate, or path, and they do not receive a request.

Filter

The Filter component is the input shown in the List view’s Filter By menu. It represents this field when an editor builds a query.
A Filter component must be a client component. FrogBot renders it without filter-specific props: it receives only the clientProps set in its component configuration. Custom filters apply to top-level fields only.

Label

The Label component is used wherever the admin panel labels a field, most commonly in Edit views.
Label component types follow the field-family convention:

Description

Use a Description component instead of the admin.description property when the description needs rich markup, live form values, or interaction.
Description component types follow the same convention:

Error

The Error component renders when field validation fails, usually beneath the input.
Error component types follow the same convention:

Diff

The Diff component renders a field in the Version Diff view and is visible only when versioning is enabled.
Diff component types follow the same convention:

afterInput and beforeInput

Use beforeInput and afterInput to add components around the input without replacing the complete Field component. Each option accepts an array, so multiple components can occupy either slot.
These slot components receive the field family’s default component props. Choose the corresponding client or server type based on whether the component uses 'use client'. Use only the curated admin hooks and field primitives exported by @frogbotai/ui/admin. General-purpose admin internals and element subpaths are not part of this contract. Component paths, server and client boundaries, and import-map generation follow the conventions above.

TypeScript

Import Field, individual field configuration types, and custom component types from frogbot. Container field types are recursive, so nested fields retain FrogBot hook, access, and validation request types.
Run frogbot generate:types to generate your application’s frogbot-types.ts declarations from the configured collections and fields. See TypeScript for generated type setup.