Areca Docs

Field types

Every field type in an Areca content type, with its settings, validation limits, how editors see it, and the value your site receives.

Use this page to choose a field type for each property of a content type, and to learn what your site receives when it pulls content. Each field has a type, a few shared settings, and some type-specific settings.

The types shown here are the ones areca.gen.ts gives each field after areca pull. Each field type maps to one TypeScript type, and the optional value shapes listed in the table are the ones the CMS sends. See typed content for how the types are generated, and reading content for the queries that use them.

Summary

There are 12 field types. Site content sections use the same types, except slug. The last two columns give the TypeScript type of a value in data, for a required field and for an optional one.

TypeLabel in the CMSRequired valueOptional valueMain limit
textShort textstringstring | null | undefined1,000 characters
textareaLong textstringstring | null | undefined50,000 characters
richtextRich textRichTextValueRichTextValue | '' | null | undefinedEntry data up to 1 MiB
imageImageImageValueImageValue | '' | null | undefinedLibrary file
dateDatestring (YYYY-MM-DD)string | null | undefinedValid calendar date
datetimeDate and timestring (ISO 8601)string | null | undefined64 characters
selectChoice'a' | 'b' with options, otherwise stringWith options: 'a' | 'b' | '' | null | undefined. Otherwise: string | null | undefinedUp to 200 options
referenceLink to entryReferenceValue<'target'>ReferenceValue<'target'> | '' | null | undefinedRequires collection
slugSlugstringstring | null | undefined200 characters, lowercase
booleanYes / nobooleanboolean | null | undefinedNone
numberNumbernumbernumber | null | undefinedNone
urlWeb addressstringstring | null | undefined2,048 characters, http or https

A missing key in the pulled JSON is the same as undefined. A required field is always present, never null and never '', because the pull rejects those values. An optional field can have any of the shapes in its column. Each collection's field keys are camelCase in code, so a field cover_image is entry.data.coverImage. The key you set in the config is the raw name.

Shared settings

Every field accepts these settings. Type-specific settings are listed in each section below.

SettingTypeRequiredDescription
keystringYesThe property name in the content data. Must start with a letter and contain only letters, digits, _ or -. Up to 64 characters. Reserved names are rejected. It cannot be changed after the field is created. See identifier rules.
labelstringYesThe name editors see. Up to 200 characters.
typeFieldTypeYesOne of the 12 types in the table above.
requiredbooleanNoWhen true, the entry cannot be marked ready or go live until the field has a value. Drafts can be saved with the field empty.
descriptionstringNoHelp text shown under the field. Up to 1,000 characters.
optionsstring[]NoChoices for a select field. Ignored by other types.
collectionstringFor referenceThe key of the collection a link can point to. Without it, the CMS refuses to save a value.
afterstringNoFor date and datetime only. The key of another date or datetime field in the same entry. This field's value must be on or after that field's value.
groupstringNoA heading shown above the field in the editor, up to 80 characters. Only for site content sections; collection fields may not set it. The SDK value is unchanged. See site content.

Optional fields that editors never filled can be null or missing from the pulled JSON. Check for both when you render.

areca.config.ts
import { defineSiteContent } from '@areca-cms/site-sdk'

export default defineSiteContent({
  siteKey: 'acme-site',
  collections: {
    articles: {
      route: '/blog/$slug',
      label: 'Articles',
      fields: [
        { key: 'title', label: 'Title', type: 'text', required: true },
        { key: 'excerpt', label: 'Excerpt', type: 'textarea', description: 'Shown in lists.' },
        { key: 'body', label: 'Body', type: 'richtext', required: true },
        { key: 'heroImage', label: 'Hero image', type: 'image' },
        { key: 'publishedAt', label: 'Published at', type: 'datetime' },
        { key: 'category', label: 'Category', type: 'select', options: ['news', 'updates'] },
      ],
    },
  },
})

Each collection's route is the URL pattern where its entries live. Use $slug in the pattern. The CMS replaces it with each entry's slug.

text

Short text. A single-line input.

  • Settings: none beyond the shared settings.
  • Validation: a string of up to 1,000 characters. A required field must not be empty.
  • Pulled value: string.
title: string

textarea

Long text. A multi-line input for plain text. It has no formatting.

  • Validation: a string of up to 50,000 characters.
  • Pulled value: string, with line breaks preserved.
excerpt?: string | null

richtext

Rich text. A formatted body with a toolbar. Editors can use:

  • Bold and italic.

  • Headings at levels 2, 3 and 4.

  • Links to http, https and mailto addresses.

  • Bulleted and numbered lists, block quotes and code blocks.

  • Tables and horizontal rules.

  • Images.

  • Validation: a required field fails when the document is empty. Other limits:

LimitValue
Nesting depth32
Nodes in one document20,000
Text characters in one document200,000
Marks on one node16

Content that uses other node types or marks is rejected. The whole entry's data must stay under 1 MiB.

  • Pulled value: a RichTextValue object. Render it with the helpers in Rich text.
type RichTextValue = {
  json: unknown        // the editor's JSON document
  markdown: string     // canonical Markdown
  document: MarkdownDocument // parsed AST, from @tanstack/markdown
  html: string         // static HTML rendered from the same AST
}

image

Image. A thumbnail area. When empty, the area is a Choose an image button. Its hint reads "From the Library, or upload a new one." Once a file is chosen, editors can Replace or Remove it. If the image has no description, the editor shows a warning, because the description becomes the alt text.

  • Validation: the value must be a file in the same client's Library. The CMS checks this when the entry is saved.
  • Library files: JPEG, PNG, WebP, GIF and PDF, up to 20 MB each.
  • Pulled value: an ImageValue object. An optional field that is empty can be null, missing or ''.
type ImageValue = {
  url: string          // local path after areca pull, e.g. /areca/hero-3f2a91c0.jpg
  width: number | null
  height: number | null
  alt: string          // the Library description, or "" if none
  mimeType: string
}

The field can point to any Library file, so check mimeType before you render the value as an <img>.

date

Date. A native date picker.

  • Validation: an ISO calendar date in the form YYYY-MM-DD.
  • Pulled value: string, for example "2026-03-01".
publishedOn: string

datetime

Date and time. A native date and time picker. The editor works in local time.

  • Validation: an ISO 8601 date and time, up to 64 characters.
  • Pulled value: string in UTC, for example "2026-03-01T09:00:00.000Z". Parse it with new Date(value).
publishedAt: string | null

select

Choice. One value from a list.

  • Editor: with four or fewer short options, editors see a segmented control. With more options, or labels too long to fit side by side, they see a dropdown. Optional fields get a Clear choice link either way.
  • Settings: options, an array of up to 200 strings. Each option can be up to 200 characters.
  • Validation: when options is set, the value must be one of them. Without options, any string of up to 500 characters is accepted.
  • Pulled value: string. If you remove an option that entries use, those entries need a new value before they can be published.
category: 'news' | 'updates'

When options is set, you can narrow the type in your interface to the same literal union.

reference

Link to entry. A picker that searches the entries of one collection. The button reads Select an entry…, and the search box reads Search entries….

  • Settings: collection is the key of the target collection. It is required.
  • Validation: the linked entry must exist in that collection. Saving a draft does not check whether the linked entry is published. Publishing the entry does.
  • Pulled value: a ReferenceValue. An optional field that is empty can be null, missing or ''.
type ReferenceValue<C extends string = string> = {
  collection: C        // camelCase key of the target collection, e.g. 'blogPosts'
  slug: string         // the target entry's slug
  id: string           // the target entry's ID
}

To link to an article from a page, make the page's related field a reference with collection: 'articles'. In your site, content.resolve(page.data.related) returns the target entry, and content.href(...) builds its link from the target collection's route. See reading content.

slug

Slug. A text input in a monospace font.

Every collection has a required slug field, named slug, added automatically as its first field. If your config defines a field with the key slug, the CMS replaces it with the built-in field, so you do not need to define one.

  • Validation: lowercase letters, digits and single hyphens, for example my-first-post. The pattern is ^[a-z0-9]+(?:-[a-z0-9]+)*$. Up to 200 characters. A required field must not be empty.
  • Pulled value: string.

The value of the slug field becomes the entry's slug, so it is what replaces $slug in the collection's route.

Site content sections have no slug. A slug field in a globals section is refused, and the push fails with an error. The CMS does not add one.

slug: string

boolean

Yes / no. A switch.

  • Validation: true or false.
  • Pulled value: boolean. An optional field that was never switched can be missing.
featured?: boolean

number

Number. A number input.

  • Validation: any JavaScript number. The CMS sets no minimum, maximum or step. Clearing the input stores null, which is accepted only when the field is optional.
  • Pulled value: number, or null when empty.
readingMinutes: number | null

url

Web address. A text input with https:// as the placeholder.

  • Validation: an absolute URL that starts with http:// or https://. Up to 2,048 characters.
  • Pulled value: string.
ctaUrl?: string

Limits at a glance

LimitValue
Collections per site manifest100
Fields per collection100
Manifest size256 KiB
Route pattern length500 characters
Field label200 characters
Field description1,000 characters
Options per select field200, each up to 200 characters
Entry data, all fields together1 MiB

Site API rate limits are covered in Errors and limits.

On this page