Field Types Reference

On this page

EmDash supports 14 field types for defining content schemas. Each type maps to a SQLite column type and provides appropriate admin UI.

Overview

TypeSQLite ColumnDescription
stringTEXTShort text input
textTEXTMulti-line text
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

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,
}

Stored as JSON array of Portable Text blocks:

[
	{
		"_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 Creating Plugins — Portable Text Block Types.

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)

Stored value:

{
	"id": "01HXK5MZSN...",
	"url": "https://cdn.example.com/image.jpg",
	"alt": "Description",
	"width": 1920,
	"height": 1080
}

file

Reference to an uploaded file (documents, PDFs, etc.).

{
  slug: "document",
  label: "Document",
  type: "file",
}

Stored value:

{
	"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)

Single reference stored value:

"01HXK5MZSN..."

Multiple references stored value:

["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
  • created_at
  • updated_at
  • published_at
  • deleted_at
  • version

TypeScript Types

Import field types for programmatic use:

import type { FieldType, Field, CreateFieldInput } from "emdash";

const fieldTypes: FieldType[] = [
	"string",
	"text",
	"number",
	"integer",
	"boolean",
	"datetime",
	"select",
	"multiSelect",
	"portableText",
	"image",
	"file",
	"reference",
	"json",
	"slug",
];