Field Types Reference

On this page

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:

TypeSQLite ColumnDescription
stringTEXTShort text input
textTEXTMulti-line text
urlTEXTURL value
numberREALDecimal number
integerINTEGERWhole number
booleanINTEGERTrue/false
datetimeTEXTDate and time
selectTEXTSingle choice from options
multiSelectJSONMultiple choices
portableTextJSONRich text content
imageTEXTImage reference
fileTEXTFile reference
referenceTEXTReference to another entry
jsonJSONArbitrary JSON data
slugTEXTURL-safe identifier
repeaterJSONRepeating 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 count
  • maxLength — Maximum character count
  • pattern — 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 count
  • maxLength — 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 value
  • max — 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 value
  • max — 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:

PropertyTypeDescription
slugstringUnique identifier (required)
labelstringDisplay name (required)
typeFieldTypeField type (required)
requiredbooleanRequire a value (default: false)
uniquebooleanEnforce uniqueness (default: false)
defaultValueunknownDefault value for new entries
validationobjectType-specific validation rules
widgetstringCustom widget override
optionsobjectWidget configuration
sortOrdernumberDisplay order in admin

Reserved field slugs

These slugs are reserved and cannot be used:

  • id
  • slug
  • status
  • author_id
  • primary_byline_id
  • created_at
  • updated_at
  • published_at
  • scheduled_at
  • deleted_at
  • version
  • live_revision_id
  • draft_revision_id
  • terms
  • bylines
  • byline

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",
];