# Collections and fields

> Choose collection behavior and field types, and understand how later changes affect content.

Source: https://emdashcmseverything.com/official-docs/concepts/collections/

A collection defines one kind of content and the form editors use to create it. Its fields define
the values each entry can contain. For example, a Products collection could contain a title, price,
description, product image, and reference to a Brand entry.

Administrators manage collections under **Content Types**. Seed files can define the same collection
settings when a site or environment is set up from configuration.

## Collection identity

Every collection has a plural label, an optional singular label, and a slug. Labels appear in the
admin panel. The slug identifies the collection in queries, API routes, seed files, and the database.

For example, a collection labelled **Blog Posts** can use **Blog Post** as its singular label and
`posts` as its slug. Astro code then queries it by that slug:

```ts
import { getEmDashCollection } from "emdash";

const { entries: posts } = await getEmDashCollection("posts");
```

Choose the slug before creating the collection. The admin panel does not rename collection slugs or
field slugs later because existing queries and stored columns depend on them. Slugs start with a
lowercase letter, contain only lowercase letters, numbers, and underscores, and have a maximum of 63
characters. EmDash also rejects reserved names used by its own routes and entry data.

## Collection behavior

Collection settings control how editors and public pages use the entries:

- **Routable** requires a public slug before an entry can be published. A URL pattern can combine
  the entry slug or ID with its publication date to produce the public path. Each placeholder
  needs its own path segment: `/{year}/{month}/{slug}.html` is valid, but `/{year}{month}/{slug}`
  and `/{slug}-{id}` are rejected.
- **Drafts** lets editors save work before publishing it.
- **Revisions** keeps snapshots of content history.
- **Preview** provides signed preview URLs for unpublished content.
- **Search** enables full-text search for fields marked as searchable.
- **SEO** adds title, description, and image metadata fields and includes the collection in the
  sitemap. See [Built-in SEO Features](https://emdashcmseverything.com/official-docs/guides/seo/).
- **Edit locking** holds an entry while one editor is working and refuses other writers until the
  lock is released.
- **Comments** can be enabled per collection, with moderation and automatic closing settings.
- **Icon** names the Phosphor icon shown next to the collection in the sidebar and command
  palette, such as `calendar-blank`; a name that does not resolve falls back to the default icon.
- **Hide from navigation** removes the sidebar entry, the command palette link, and the dashboard
  quick action while the collection stays reachable by URL, API, and plugins. Turning off **Quick action on the
  dashboard** removes only the quick action, for collections that plugins or imports fill rather
  than editors.
- **Group** places the collection in a collapsible sidebar folder. Collections with the same group
  share one folder, positioned where the first of them would appear. A taxonomy joins the folder when
  every collection it is assigned to is shown in that folder.

Enable behavior that the site actually uses. For example, turning on Preview supplies preview URLs,
but the Astro page must still render the entry and its preview state correctly. See [Preview
mode](https://emdashcmseverything.com/official-docs/guides/preview/) for that complete flow.

## Field types

Choose a field type for the value editors enter and the way application code receives it. EmDash
supports 17 field types:

| Content need | Field types | What editors work with |
| --- | --- | --- |
| Short or long text | `string`, `text`, `slug`, `url` | Text inputs, text areas, and URL values |
| Numbers | `number`, `integer` | Decimal or whole-number inputs |
| State and time | `boolean`, `datetime` | A switch or date-and-time picker |
| Fixed choices | `select`, `multiSelect` | One or several choices from configured options |
| Rich or structured data | `portableText`, `json`, `repeater`, `blocks` | Rich text, JSON, repeated groups, or an ordered block composition |
| Media | `image`, `file` | An item selected from the media library |
| Relationships | `reference` | An entry selected from another collection |

The type is more than an editor control. It also determines how EmDash stores and validates the
value and how generated TypeScript declarations describe it. The [field types
reference](https://emdashcmseverything.com/official-docs/reference/field-types/) lists each type's value shape and options.

## Field rules

Every custom field has a label and slug. The following options further describe its behavior:

- **Required** prevents an entry from being saved without a value.
- **Unique** prevents two entries in the collection from using the same value.
- **Default value** supplies a starting value when appropriate.
- **Validation** can limit text length, number ranges, patterns, choices, file types, or repeater
  length according to the field type.
- **Searchable** includes supported text fields in the collection's full-text search index.
- **Indexed** creates a database index for sorting or filtering on a supported field.
- **Translatable** controls whether each locale has its own value. A non-translatable value is shared
  across translations of the same entry.

Turn on **Indexed** when a query sorts or filters by that custom field. The index helps the database
find matching or ordered entries, but it uses additional storage and adds work whenever content is
created or updated. Do not index a field only because a page displays it.

Indexes are available for `string`, `url`, `number`, `integer`, `boolean`, `datetime`, `select`,
`reference`, and `slug` fields. Rich text, JSON, repeaters, and multiple-choice values contain more
complex data and cannot use this kind of index.

A reference field stores nothing in the collection's own table. Configure it with the target
collection, and allow multiple values only when the field should link several entries. EmDash keeps
the links separately and returns the linked entries under `references` rather than in `data`, so a
reference lets code load or identify related content without copying the target entry into the
source entry. See [`reference`](https://emdashcmseverything.com/official-docs/reference/field-types/#reference) for the stored shape and the
behavior of a field with no target collection, and [Relations](https://emdashcmseverything.com/official-docs/guides/relations/) for the workflow
around it.

## Changing fields later

Labels, validation, search settings, indexes, widget options, and display order can change without
replacing the field. Adding a field keeps every existing entry, although those entries need a value
for the new field if the site expects one.

> **Some schema changes remove data or require migration**
>
> Deleting a field drops its database column and removes that field's value from every entry.
> Deleting a collection drops its content table and all entries in the collection. Back up
> production data before either action.
>
> The admin panel keeps the type and slug of an existing field fixed. The schema API only permits
> in-place type changes among `string`, `text`, and `slug`. All other retypes can change the storage
> shape and require a content migration. Changing `required` or `unique`, or changing a translatable
> field to non-translatable, also requires a migration.

The migration must convert existing values, update the model, and keep old and new application code
compatible during deployment. Follow [Evolving a deployed site's
schema](https://emdashcmseverything.com/official-docs/deployment/schema-evolution/) before making one of these changes.

## Related tasks

Use [Working with content](https://emdashcmseverything.com/official-docs/guides/working-with-content/) to create and publish entries. Use
[Querying content](https://emdashcmseverything.com/official-docs/guides/querying-content/) to filter and sort them. Read [Content
model](https://emdashcmseverything.com/official-docs/concepts/content-model/) for generated types and seed files.
