> ## 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.

# Collections

> What a CMS collection is, how to create one, and reusable patterns for common content types

A **collection** is a group of entries that share the same shape — for example, "Blog Posts," "Products," or "Team Members." Each collection has a single schema (its fields) and lives in a single directory on disk. Most sites need three to ten collections; some need only one.

This page covers what a collection is, the three ways to create one, naming and format conventions, references between collections, and ready-to-use patterns for common content types.

## What's in a Collection?

Every collection in your [manifest](/cms/manifest) has:

* An **id** — the stable identifier (`blog`, `products`, `case-studies`)
* A **name** — the human label shown in the CMS panel
* A **path** — where entries live on disk (`content/blog/`)
* A **format** — `mdx` (frontmatter + body) or `json` (structured data only)
* **Fields** — the schema each entry must conform to
* An optional **routePattern** — the URL each entry maps to
* An optional **defaultSort** for the entry list view

Each entry in the collection becomes one file in the directory.

## Creating a Collection

There are three paths. Pick whichever matches your comfort level.

<Tabs>
  <Tab title="Ask the AI">
    The fastest way. In the AI chat:

    ```
    Add a "case-studies" collection. Each entry should have a title,
    client name, problem, solution, hero image, and a long-form body.
    Route them at /case-studies/{slug}.
    ```

    The AI will:

    1. Read your existing manifest
    2. Propose the collection schema (fields, format, route)
    3. Confirm with you
    4. Save the manifest update
    5. Optionally create a seed entry so the collection isn't empty

    See [Add a New Collection](/how-tos/add-collection) for the full step-by-step.
  </Tab>

  <Tab title="CMS Panel">
    Open `/v3`, switch the right pane to **CMS**, and click the gear icon to open the **Collection Manager**. Click **+ New Collection** and define the fields one at a time. The Collection Manager validates as you type and shows the resulting manifest preview on the right.
  </Tab>

  <Tab title="Manual edit">
    Open `hiveku.cms.json` in the code editor and add a new entry to the `collections` array. Follow the [manifest schema](/cms/manifest). Save — the CMS panel reloads and validates.
  </Tab>
</Tabs>

## Naming Conventions

A few rules to keep things consistent across collections:

* **`id`** — lowercase, hyphenated, singular when ambiguous. Good: `blog`, `case-study`, `team-member`. Avoid: `blog_posts`, `BlogPosts`, `posts` (too generic).
* **`name`** — Title Case, plural. Good: `Blog Posts`, `Case Studies`, `Team Members`.
* **`path`** — `content/<id>` or `content/<plural>`. Whichever you pick, be consistent across the manifest.
* **Field `name`** — camelCase. Good: `publishedAt`, `heroImage`, `seoTitle`. Avoid: `published_at`, `Hero-Image`.

## Format: MDX vs JSON

Pick `mdx` when entries have a substantial long-form body and you want Markdown features (headings, embeds, components) in that body. Pick `json` for purely structured data.

| Use MDX for...      | Use JSON for... |
| ------------------- | --------------- |
| Blog posts          | Testimonials    |
| Case studies        | FAQs            |
| Documentation pages | Products        |
| Long-form essays    | Team members    |
| Tutorials           | Pricing tiers   |
| Newsletters         | Site settings   |

<Info>
  MDX collections require exactly one field with `isBody: true`. JSON collections must not have any. The Collection Manager catches this for you; if you hand-edit the manifest, the validator will too.
</Info>

You can mix formats in one project — most real sites have one or two MDX collections (blog, docs) and several JSON collections (products, testimonials, FAQs).

## References Between Collections

A `reference` field lets one collection point at another. Common patterns:

* A `blog` post `references` an entry in `authors`
* A `case-study` references one or more `products`
* A `product` references entries in `categories`
* A `blog` post references related entries in `blog` itself (self-reference is allowed)

In the manifest:

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

In the CMS panel, this renders as a searchable picker. On disk, the value is the referenced entry's slug. See [Linking Collections with References](/how-tos/cms-references) for examples of rendering referenced data on the page.

## Reusable Patterns

Below are battle-tested schemas for the most common collection types. Use them as starting points and adapt fields to your site.

### Blog

```json theme={null}
{
  "id": "blog",
  "name": "Blog Posts",
  "path": "content/blog",
  "format": "mdx",
  "slugFrom": "filename",
  "fields": [
    { "name": "title", "type": "string", "required": true },
    { "name": "excerpt", "type": "string", "multiline": true, "maxLength": 280 },
    { "name": "publishedAt", "type": "date", "required": true },
    { "name": "status", "type": "select", "options": ["draft", "published"], "default": "draft" },
    { "name": "author", "type": "reference", "collection": "authors", "required": true },
    { "name": "heroImage", "type": "image" },
    { "name": "tags", "type": "array", "items": "string" },
    { "name": "body", "type": "markdown", "isBody": true }
  ],
  "routePattern": "/blog/{slug}",
  "defaultSort": "publishedAt desc"
}
```

### Products (catalog)

```json theme={null}
{
  "id": "products",
  "name": "Products",
  "path": "content/products",
  "format": "json",
  "slugFrom": "filename",
  "fields": [
    { "name": "name", "type": "string", "required": true },
    { "name": "sku", "type": "string", "required": true },
    { "name": "price", "type": "number", "required": true, "min": 0 },
    { "name": "currency", "type": "select", "options": ["USD", "EUR", "GBP"], "default": "USD" },
    { "name": "inStock", "type": "boolean", "default": true },
    { "name": "images", "type": "array", "items": "image" },
    { "name": "shortDescription", "type": "string", "multiline": true, "maxLength": 280 },
    { "name": "longDescription", "type": "markdown" },
    { "name": "category", "type": "reference", "collection": "categories" }
  ],
  "routePattern": "/products/{slug}",
  "defaultSort": "name asc"
}
```

### Team Members

```json theme={null}
{
  "id": "team",
  "name": "Team Members",
  "path": "content/team",
  "format": "json",
  "slugFrom": "field:name",
  "fields": [
    { "name": "name", "type": "string", "required": true },
    { "name": "title", "type": "string", "required": true },
    { "name": "bio", "type": "markdown" },
    { "name": "photo", "type": "image", "metadata": true },
    { "name": "email", "type": "string" },
    { "name": "linkedin", "type": "url" },
    { "name": "twitter", "type": "url" },
    { "name": "order", "type": "number", "integer": true, "default": 0 }
  ],
  "defaultSort": "order asc"
}
```

### Testimonials

```json theme={null}
{
  "id": "testimonials",
  "name": "Testimonials",
  "path": "content/testimonials",
  "format": "json",
  "slugFrom": "filename",
  "fields": [
    { "name": "name", "type": "string", "required": true },
    { "name": "company", "type": "string" },
    { "name": "role", "type": "string" },
    { "name": "quote", "type": "string", "multiline": true, "required": true },
    { "name": "avatar", "type": "image" },
    { "name": "featured", "type": "boolean", "default": false },
    { "name": "rating", "type": "number", "integer": true, "min": 1, "max": 5 }
  ],
  "defaultSort": "featured desc"
}
```

### FAQs

```json theme={null}
{
  "id": "faqs",
  "name": "FAQs",
  "path": "content/faqs",
  "format": "json",
  "slugFrom": "filename",
  "fields": [
    { "name": "question", "type": "string", "required": true },
    { "name": "answer", "type": "markdown", "required": true },
    { "name": "category", "type": "select", "options": ["billing", "technical", "general"], "default": "general" },
    { "name": "order", "type": "number", "integer": true, "default": 0 }
  ],
  "defaultSort": "category asc"
}
```

### Case Studies

```json theme={null}
{
  "id": "case-studies",
  "name": "Case Studies",
  "path": "content/case-studies",
  "format": "mdx",
  "slugFrom": "filename",
  "fields": [
    { "name": "title", "type": "string", "required": true },
    { "name": "client", "type": "string", "required": true },
    { "name": "industry", "type": "string" },
    { "name": "summary", "type": "string", "multiline": true, "maxLength": 320 },
    { "name": "heroImage", "type": "image" },
    { "name": "metrics", "type": "array", "items": {
        "type": "object",
        "fields": [
          { "name": "label", "type": "string", "required": true },
          { "name": "value", "type": "string", "required": true }
        ]
    } },
    { "name": "publishedAt", "type": "date" },
    { "name": "body", "type": "markdown", "isBody": true }
  ],
  "routePattern": "/case-studies/{slug}",
  "defaultSort": "publishedAt desc"
}
```

### Site Settings (singleton)

```json theme={null}
{
  "id": "site-settings",
  "name": "Site Settings",
  "path": "content/site-settings",
  "format": "json",
  "singleton": true,
  "fields": [
    { "name": "siteName", "type": "string", "required": true },
    { "name": "tagline", "type": "string" },
    { "name": "logo", "type": "image" },
    { "name": "primaryColor", "type": "color" },
    { "name": "footerText", "type": "markdown" },
    { "name": "socialLinks", "type": "object", "fields": [
        { "name": "twitter", "type": "url" },
        { "name": "linkedin", "type": "url" },
        { "name": "github", "type": "url" }
    ] }
  ]
}
```

## Editing a Collection's Schema

You can edit an existing collection's schema at any time:

* **Add a field** — safe. Existing entries get the new field's default; the form shows it on next open.
* **Remove a field** — safe but lossy. The data stays in the file; re-adding a field with the same name restores the editor.
* **Rename a field** — invasive. Old data is orphaned. Ask the AI to write a migration if you have many entries.
* **Change a field's type** — risky. Some types are convertible (`string` to `markdown`); most aren't. Test on a draft branch.

<Tip>
  Before any large schema change, snapshot the project. The version history drawer captures every manifest edit, so you can always roll back.
</Tip>

## Singleton Collections

Set `"singleton": true` on a collection to enforce a single entry — useful for site settings, the homepage hero, or a single about page. The CMS panel skips the entry list and goes straight to the form.

## What's Next?

<CardGroup cols={2}>
  <Card title="Add a Collection" icon="plus" href="/how-tos/add-collection">
    Three paths to add a new collection
  </Card>

  <Card title="Field Types" icon="list" href="/cms/field-types">
    Every supported field type
  </Card>

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

  <Card title="Migrate to CMS" icon="arrow-right-arrow-left" href="/how-tos/migrate-site-to-cms">
    Move hardcoded content into CMS collections
  </Card>
</CardGroup>
