> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hiveku.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Field Types

> Every field type supported by the Hiveku CMS — what each one stores, how it renders in the editor, and when to use it

The CMS form editor is built directly from the field definitions in your [manifest](/cms/manifest). Each field's `type` decides what the input control looks like, how data is validated, and how the value is stored on disk.

This page is the full reference. Pick the type that matches the kind of data, and the editor takes care of the rest.

## Common Field Properties

Every field type accepts these properties:

| Property      | Type    | Description                                                                                        |
| ------------- | ------- | -------------------------------------------------------------------------------------------------- |
| `name`        | string  | Required. The key under which the value is stored. Lowercase, valid identifier.                    |
| `type`        | string  | Required. One of the types listed below.                                                           |
| `label`       | string  | Optional human-readable label shown in the form. Defaults to a Title-Cased `name`.                 |
| `description` | string  | Optional helper text shown below the input.                                                        |
| `required`    | boolean | If `true`, the entry won't save without a value.                                                   |
| `default`     | any     | Default value for new entries.                                                                     |
| `hidden`      | boolean | If `true`, the field exists in the schema but is not shown in the form (useful for system fields). |

Type-specific properties (like `options` for `select` or `collection` for `reference`) are documented per type below.

## string

A single-line text value.

**UI:** A text input, or a `textarea` if `multiline: true`.

**Stores:** A JSON string in the entry file.

**Properties:**

| Property    | Description                                      |
| ----------- | ------------------------------------------------ |
| `multiline` | Render a textarea instead of a single-line input |
| `maxLength` | Maximum character count                          |
| `pattern`   | Regex pattern the value must match               |

```json theme={null}
{ "name": "title", "type": "string", "required": true, "maxLength": 80 }
```

```json theme={null}
{ "name": "excerpt", "type": "string", "multiline": true, "maxLength": 280 }
```

## number

A numeric value (integer or floating point).

**UI:** A numeric input with optional min/max/step.

**Stores:** A JSON number.

**Properties:**

| Property  | Description                                |
| --------- | ------------------------------------------ |
| `min`     | Minimum allowed value                      |
| `max`     | Maximum allowed value                      |
| `step`    | Step increment (use `1` for integers)      |
| `integer` | If `true`, only whole numbers are accepted |

```json theme={null}
{ "name": "price", "type": "number", "required": true, "min": 0 }
```

```json theme={null}
{ "name": "readingTime", "type": "number", "integer": true, "min": 1 }
```

## boolean

A true/false value.

**UI:** A toggle switch.

**Stores:** `true` or `false` JSON literal.

```json theme={null}
{ "name": "featured", "type": "boolean", "default": false }
```

## date

An ISO-8601 date or datetime.

**UI:** A date picker (or datetime picker if `time: true`).

**Stores:** A JSON string in `YYYY-MM-DD` or full ISO format.

**Properties:**

| Property | Description                             |
| -------- | --------------------------------------- |
| `time`   | If `true`, capture time as well as date |

```json theme={null}
{ "name": "publishedAt", "type": "date", "time": true, "required": true }
```

## markdown

Long-form Markdown content.

**UI:** A split-pane editor with live preview, syntax highlighting, image drop, and shortcuts. The same control is used for the body of MDX entries when `isBody: true`.

**Stores:** Markdown source — either as a JSON string (for JSON collections) or as the body of the MDX file (when `isBody: true`).

**Properties:**

| Property | Description                                                                                                           |
| -------- | --------------------------------------------------------------------------------------------------------------------- |
| `isBody` | When `true` on an MDX collection, this field becomes the body of the file. Exactly one body field per MDX collection. |

```json theme={null}
{ "name": "body", "type": "markdown", "isBody": true }
```

```json theme={null}
{ "name": "longDescription", "type": "markdown" }
```

<Tip>
  MDX bodies support React components imported from your project — useful for embedding charts, callouts, or custom layouts inside long-form content.
</Tip>

## color

A color value.

**UI:** A color picker with hex input.

**Stores:** A JSON string in `#rrggbb` or `#rrggbbaa` form.

```json theme={null}
{ "name": "accent", "type": "color", "default": "#3b82f6" }
```

## url

A URL.

**UI:** A text input with URL validation.

**Stores:** A JSON string. Validated against URL syntax on save.

```json theme={null}
{ "name": "website", "type": "url" }
```

## image

An image asset.

**UI:** An upload dropzone with drag-and-drop, paste support, and an "Choose existing" button that opens the project's media library. Resizes and serves through Hiveku's image CDN automatically.

**Stores:** A JSON string with the path to the uploaded file (e.g. `/uploads/hero.jpg`), or an object with `src`, `alt`, `width`, `height` if `metadata: true`.

**Properties:**

| Property   | Description                                                           |
| ---------- | --------------------------------------------------------------------- |
| `metadata` | If `true`, store `{ src, alt, width, height }` instead of just a path |
| `accept`   | Comma-separated list of MIME types (default `image/*`)                |

```json theme={null}
{ "name": "heroImage", "type": "image", "metadata": true }
```

## file

A non-image file asset (PDF, video, audio, archives).

**UI:** Same upload dropzone as `image`, with a generic file preview.

**Stores:** A JSON string with the upload path.

**Properties:**

| Property  | Description                                              |
| --------- | -------------------------------------------------------- |
| `accept`  | MIME types or extensions (e.g. `"application/pdf,.zip"`) |
| `maxSize` | Maximum file size in bytes                               |

```json theme={null}
{ "name": "datasheet", "type": "file", "accept": "application/pdf" }
```

## select

One of a fixed set of values.

**UI:** A dropdown (or a radio group for short option lists).

**Stores:** A JSON string matching one of the option values.

**Properties:**

| Property   | Description                                                                |
| ---------- | -------------------------------------------------------------------------- |
| `options`  | Array of option strings, or `[{ value, label }]` objects for custom labels |
| `multiple` | If `true`, becomes a multi-select that stores an array                     |

```json theme={null}
{
  "name": "status",
  "type": "select",
  "options": ["draft", "published", "archived"],
  "default": "draft"
}
```

```json theme={null}
{
  "name": "category",
  "type": "select",
  "options": [
    { "value": "news", "label": "News & Updates" },
    { "value": "tutorial", "label": "Tutorials" },
    { "value": "case-study", "label": "Case Studies" }
  ]
}
```

## array

A list of values, all of the same shape.

**UI:** A reorderable list with add/remove buttons. Each row renders the editor for the `items` type.

**Stores:** A JSON array.

**Properties:**

| Property   | Description                                                                                                                                           |
| ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| `items`    | The type of each element. Can be a primitive (`"string"`, `"number"`, `"image"`) or a full field definition (`{ "type": "object", "fields": [...] }`) |
| `minItems` | Minimum number of items                                                                                                                               |
| `maxItems` | Maximum number of items                                                                                                                               |

```json theme={null}
{ "name": "tags", "type": "array", "items": "string" }
```

```json theme={null}
{ "name": "gallery", "type": "array", "items": "image", "maxItems": 12 }
```

```json theme={null}
{
  "name": "features",
  "type": "array",
  "items": {
    "type": "object",
    "fields": [
      { "name": "title", "type": "string", "required": true },
      { "name": "icon", "type": "string" },
      { "name": "description", "type": "string", "multiline": true }
    ]
  }
}
```

## object

A grouped set of fields edited together.

**UI:** A collapsible group of nested form controls.

**Stores:** A nested JSON object.

**Properties:**

| Property | Description                                               |
| -------- | --------------------------------------------------------- |
| `fields` | The list of nested fields, each a normal field definition |

```json theme={null}
{
  "name": "seo",
  "type": "object",
  "fields": [
    { "name": "title", "type": "string", "maxLength": 60 },
    { "name": "description", "type": "string", "multiline": true, "maxLength": 160 },
    { "name": "ogImage", "type": "image" }
  ]
}
```

## reference

A pointer to another collection's entry.

**UI:** A picker that opens a searchable list of entries from the target collection. The picker shows each entry's title field for easy identification.

**Stores:** A JSON string with the referenced entry's slug, or an array of slugs if `multiple: true`.

**Properties:**

| Property       | Description                                                      |
| -------------- | ---------------------------------------------------------------- |
| `collection`   | Required. The target collection's `id`.                          |
| `multiple`     | If `true`, stores an array of references                         |
| `displayField` | Field name to show in the picker (defaults to `title` or `name`) |

```json theme={null}
{ "name": "author", "type": "reference", "collection": "authors", "required": true }
```

```json theme={null}
{
  "name": "relatedPosts",
  "type": "reference",
  "collection": "blog",
  "multiple": true,
  "displayField": "title"
}
```

See [Linking Collections with References](/how-tos/cms-references) for full examples and how to render referenced data on the page.

## Choosing a Type

A few rules of thumb:

* **Long-form prose with formatting?** `markdown` (and `isBody: true` if it's the main body of an MDX entry).
* **Short text?** `string`. Add `multiline: true` for things like excerpts or short descriptions.
* **A fixed set of choices?** `select`. Use `multiple: true` for multi-select.
* **A list of similar things?** `array`. Set `items` to a primitive or to an `object` for richer rows.
* **A pointer to another piece of content?** `reference`. Don't duplicate fields across collections — link them.
* **Something that should just be one record?** Use a singleton collection (manifest-level `singleton: true`) and put your fields directly on it.

<Warning>
  Once an entry has data for a field, removing the field from the manifest hides it from the form but leaves the value in the file. Re-adding the field restores the editor. Renaming a field is more invasive — ask the AI to migrate the data.
</Warning>

## What's Next?

<CardGroup cols={2}>
  <Card title="The Manifest" icon="file-code" href="/cms/manifest">
    How fields fit into the larger manifest schema
  </Card>

  <Card title="Collections" icon="layer-group" href="/cms/collections">
    Reusable patterns for blog, products, and more
  </Card>

  <Card title="References" icon="link" href="/how-tos/cms-references">
    Link collections together with reference fields
  </Card>

  <Card title="Editing Content" icon="pencil" href="/cms/editing-content">
    See how each field type renders in the CMS panel
  </Card>
</CardGroup>
