Field Types
Field types define the shape of data in a collection or global. Every field shares the FieldBase properties, then adds type-specific options. This page lists all built-in types.
For the common FieldBase properties (key, label, description, required, hidden, searchable, indexed, localized, defaultValue, validate, access), see Content Model.
Text fields
Four text field types. The choice is about what editors do with them. text for single-line values like titles. textarea for plain multi-line text like summaries. markdown when editors write prose with formatting and you want HTML output. code when the content is source and you want a language hint. If you’re not sure, start with text.
text
A single-line string. Use it for titles, names, and short values.
{ key: "title", type: "text", required: true, minLength: 1, maxLength: 120 }Options: minLength, maxLength.
slug
A URL-safe string. The runtime generates it from another field if you pair it with a text field, but you can also set it manually. Use a slug field on any collection you want to query by findBySlug.
{ key: "slug", type: "slug", required: true }Options: minLength, maxLength.
textarea
A multi-line string. Use it for summaries, descriptions, and longer plain-text values.
{ key: "summary", type: "textarea", maxLength: 500 }Options: minLength, maxLength.
markdown
Markdown text. The runtime stores the raw markdown and produces a sanitized bodyHtml companion on read. Frontends render the HTML directly without a client-side markdown pipeline.
{ key: "body", type: "markdown" }Options: minLength, maxLength.
code
Source code with an optional language hint. Use it for snippets, configuration blocks, and embedded code.
{ key: "snippet", type: "code", language: "typescript" }Options: language, minLength, maxLength.
json
Free-form JSON. Stored and returned as-is. Use it when the shape is open-ended and validation happens outside the schema.
{ key: "metadata", type: "json" }email
An email address. The runtime validates the format.
{ key: "contactEmail", type: "email" }url
A URL with optional protocol restrictions.
{ key: "website", type: "url", allowedProtocols: ["https"] }Options: allowedProtocols (array of protocol strings).
color
A color value in a chosen format.
{ key: "accentColor", type: "color", format: "hex" }Options: format ("hex", "rgb", or "hsl").
Numeric and boolean fields
number for any numeric value. boolean for true/false flags. If you need a small set of named numeric states (status codes, severity levels), consider select instead of number.
number
A numeric value with optional bounds and step control.
{ key: "readingTime", type: "number", min: 0, integer: true }Options: min, max, integer, step.
boolean
A true or false value.
{ key: "featured", type: "boolean", defaultValue: false }Date field
date
An ISO date string. Use it for publish dates, event dates, and timestamps you control explicitly.
{ key: "date", type: "date" }Selection field
select
A value chosen from a fixed list of strings. Pass the allowed values as an array.
{ key: "status", type: "select", options: ["draft", "published"], defaultValue: "draft" }Options: options (array of strings).
Relational fields
relation connects to other documents. upload connects to uploaded files. Use relation when the target is content you manage in another collection. Use upload when the target is a file. Both support many: true for one-to-many.
relation
A reference to documents in another collection. Set to to the target collection key. Set many to true for a one-to-many relation.
{ key: "tags", type: "relation", to: "tags", many: true }{ key: "author", type: "relation", to: "users" }Options: to (collection key or array of keys), many, filterOptions.
Relations resolve lazily. Pass include and depth in your query to expand related documents in one request. See the HTTP API Reference.
upload
A reference to an uploaded asset. Set many to true for a gallery. Restrict file types with allowedMimeTypes and cap size with maxSize.
{ key: "featuredImage", type: "upload" }{ key: "gallery", type: "upload", many: true, allowedMimeTypes: ["image/png", "image/jpeg"], maxSize: 5242880 }Options: many, allowedMimeTypes, maxSize, imageSizes (array of { name, width?, height?, crop? }), focalPoint.
See Storage and Uploads for how uploads are handled and served.
Structural fields
Three structural types for nesting and layout. group for a fixed composite value (an address, a social link). array for a repeatable nested item (a list of social links, a list of features). tabs, row, and collapsible are layout-only and don’t change how data is stored.
group
A fixed set of nested fields stored as one object. Use it for composite values that always travel together.
{ key: "address", type: "group", fields: [ { key: "street", type: "text", required: true }, { key: "city", type: "text", required: true }, { key: "zip", type: "text" },]}Options: fields (array of field definitions).
array
A repeatable nested field. The of property takes a full field definition, so each array item can be a group with its own fields.
{ key: "socialLinks", type: "array", of: { key: "socialLink", type: "group", fields: [ { key: "label", type: "text", required: true }, { key: "url", type: "text", required: true }, ],}}Options: of (a field definition).
tabs
Split fields across named tabs. Each tab has a label and its own fields array.
{ key: "layout", type: "tabs", tabs: [ { label: "Content", fields: [{ key: "body", type: "markdown" }] }, { label: "SEO", fields: [{ key: "seoTitle", type: "text" }] },]}Options: tabs (array of { key?, label, fields }).
row
Place fields side by side on one row. Layout only. Does not change how data is stored.
{ key: "dimensions", type: "row", fields: [ { key: "width", type: "number" }, { key: "height", type: "number" },]}Options: fields (array of field definitions).
collapsible
Wrap fields in a collapsible panel. Layout only.
{ key: "advanced", type: "collapsible", label: "Advanced", fields: [ { key: "cacheTtl", type: "number" },]}Options: label, fields.
blocks
A repeatable field where each item is one of several block types. Use it for page-builder-style content where the order and type of items varies.
{ key: "content", type: "blocks", types: [ { key: "heading", fields: [{ key: "text", type: "text" }] }, { key: "image", fields: [{ key: "src", type: "upload" }] },], minRows: 1, maxRows: 20 }Options: types (array of block definitions), minRows, maxRows.
Special fields
virtual for computed values that don’t persist (an excerpt derived from the body). point for geographic coordinates. custom for field types registered by plugins.
virtual
A field that does not store data. The resolve function computes the value at read time from the document and the runtime context.
{ key: "excerpt", type: "virtual", resolve: (doc, context) => { const body = typeof doc.body === "string" ? doc.body : ""; return body.slice(0, 160);}}Options: resolve (a VirtualFieldResolver function).
point
A geographic point with latitude and longitude.
{ key: "location", type: "point" }custom
A field with a type not in the built-in list. Plugins register custom field types with their own validation, normalization, and serialization. Use the plugin’s documented type string.
{ key: "seoScore", type: "seoScore" }See also
- Content Model: collections, globals, and relations in context
- Configuration: how to wire fields into
defineCMS - Plugins: how plugins register custom field types
- HTTP API Reference: how field values are returned in API responses