EmDash supports 16 field types for defining content schemas. Each type maps to a SQLite column type and provides appropriate admin UI.
Overview
The following table lists every field type and its SQLite column:
| Type | SQLite Column | Description |
|---|---|---|
string | TEXT | Short text input |
text | TEXT | Multi-line text |
url | TEXT | URL value |
number | REAL | Decimal number |
integer | INTEGER | Whole number |
boolean | INTEGER | True/false |
datetime | TEXT | Date and time |
select | TEXT | Single choice from options |
multiSelect | JSON | Multiple choices |
portableText | JSON | Rich text content |
image | TEXT | Image reference |
file | TEXT | File reference |
reference | TEXT | Reference to another entry |
json | JSON | Arbitrary JSON data |
slug | TEXT | URL-safe identifier |
repeater | JSON | Repeating group of fields |
Text Types
string
Short, single-line text. Use for titles, names, and short values.
{
slug: "title",
label: "Title",
type: "string",
required: true,
validation: {
minLength: 1,
maxLength: 200,
},
}
Validation options:
minLength— Minimum character countmaxLength— Maximum character countpattern— Regex pattern to match
Widget options:
- None specific
text
Multi-line plain text. Use for descriptions, excerpts, and longer plain text.
{
slug: "excerpt",
label: "Excerpt",
type: "text",
options: {
rows: 3,
},
}
Validation options:
minLength— Minimum character countmaxLength— Maximum character count
Widget options:
rows— Number of rows in textarea (default: 3)
slug
URL-safe identifier. Automatically generated from another field or manually entered.
{
slug: "slug",
label: "URL Slug",
type: "slug",
required: true,
unique: true,
}
Slugs are automatically sanitized: lowercased, spaces replaced with hyphens, special characters removed.
Number Types
number
Decimal number. Use for prices, ratings, and measurements.
{
slug: "price",
label: "Price",
type: "number",
required: true,
validation: {
min: 0,
max: 999999.99,
},
}
Validation options:
min— Minimum valuemax— Maximum value
Stored as SQLite REAL (64-bit floating point).
integer
Whole number. Use for quantities, counts, and order values.
{
slug: "quantity",
label: "Quantity",
type: "integer",
defaultValue: 1,
validation: {
min: 0,
max: 1000,
},
}
Validation options:
min— Minimum valuemax— Maximum value
Stored as SQLite INTEGER.
boolean
True or false. Use for toggles and flags.
{
slug: "featured",
label: "Featured",
type: "boolean",
defaultValue: false,
}
Stored as SQLite INTEGER (0 or 1).
Date and Time
datetime
Date and time value. Stored in ISO 8601 format.
{
slug: "publishedAt",
label: "Published At",
type: "datetime",
}
Validation options:
min— Minimum date (ISO string)max— Maximum date (ISO string)
Storage format: 2025-01-24T12:00:00.000Z
Selection Types
select
Single selection from predefined options.
{
slug: "status",
label: "Status",
type: "select",
required: true,
defaultValue: "draft",
validation: {
options: ["draft", "published", "archived"],
},
}
Validation options:
options— Array of allowed values (required)
Stored as TEXT containing the selected value.
multiSelect
Multiple selections from predefined options.
{
slug: "tags",
label: "Tags",
type: "multiSelect",
validation: {
options: ["news", "tutorial", "review", "opinion"],
},
}
Validation options:
options— Array of allowed values (required)
Stored as JSON array: ["news", "tutorial"]
Rich Content
portableText
Rich text content using Portable Text format. Supports headings, lists, links, images, and custom blocks.
{
slug: "content",
label: "Content",
type: "portableText",
required: true,
}
The value is stored as a JSON array of Portable Text blocks, for example:
[
{
"_type": "block",
"style": "normal",
"children": [{ "_type": "span", "text": "Hello world" }]
}
]
Plugins can add custom block types (embeds, widgets, etc.) to the editor. These appear in the slash command menu and are automatically rendered on the site. See Portable Text rendering components.
Media Types
image
Reference to an uploaded image. Includes metadata like dimensions and alt text.
{
slug: "featuredImage",
label: "Featured Image",
type: "image",
options: {
showPreview: true,
},
}
Widget options:
showPreview— Show image preview in admin (default: true)
The value is stored as an object with the media reference and its metadata:
{
"id": "01HXK5MZSN...",
"url": "https://cdn.example.com/image.jpg",
"alt": "Description",
"width": 1920,
"height": 1080
}
file
Reference to an uploaded file such as a document or PDF.
{
slug: "document",
label: "Document",
type: "file",
}
The value is stored as an object with the file reference and its metadata:
{
"id": "01HXK5MZSN...",
"url": "https://cdn.example.com/doc.pdf",
"filename": "report.pdf",
"mimeType": "application/pdf",
"size": 102400
}
Relational Types
reference
Reference to another content entry.
{
slug: "author",
label: "Author",
type: "reference",
required: true,
options: {
collection: "authors",
},
}
Widget options:
collection— Target collection slug (required)allowMultiple— Allow multiple references (default: false)
A single reference is stored as the target entry ID:
"01HXK5MZSN..."
Multiple references are stored as an array of entry IDs:
["01HXK5MZSN...", "01HXK6NATS..."]
Flexible Types
json
Arbitrary JSON data. Use for complex nested structures, third-party integrations, or data without a fixed schema.
{
slug: "metadata",
label: "Metadata",
type: "json",
}
Stored as-is in SQLite JSON column.
Field properties
All fields support these common properties:
| Property | Type | Description |
|---|---|---|
slug | string | Unique identifier (required) |
label | string | Display name (required) |
type | FieldType | Field type (required) |
required | boolean | Require a value (default: false) |
unique | boolean | Enforce uniqueness (default: false) |
defaultValue | unknown | Default value for new entries |
validation | object | Type-specific validation rules |
widget | string | Custom widget override |
options | object | Widget configuration |
sortOrder | number | Display order in admin |
Reserved field slugs
These slugs are reserved and cannot be used:
idslugstatusauthor_idprimary_byline_idcreated_atupdated_atpublished_atscheduled_atdeleted_atversionlive_revision_iddraft_revision_idtermsbylinesbyline
TypeScript types
Import the field type definitions for programmatic use:
import type { FieldType, Field, CreateFieldInput } from "emdash";
const fieldTypes: FieldType[] = [
"string",
"text",
"url",
"number",
"integer",
"boolean",
"datetime",
"select",
"multiSelect",
"portableText",
"image",
"file",
"reference",
"json",
"slug",
"repeater",
];