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

# Editing Content in the CMS Panel

> A walkthrough of the /v3 editor's CMS mode — collection picker, entry list, form editor, version history, and bulk actions

The CMS panel is the day-to-day editing surface for everyone who isn't writing code. It lives in the right pane of the [/v3 editor](/v3/editor/overview). Switch the pane to **CMS** mode to get a Webflow-style editing experience for the structured content declared in your [manifest](/cms/manifest).

This page is a tour of every part of the panel.

## Opening the CMS Panel

<Steps>
  <Step title="Open your project in /v3">
    From the [dashboard](https://app.hiveku.com/dashboard), click your project to open it in the editor.
  </Step>

  <Step title="Switch the right pane to CMS">
    The right pane has three modes — Preview, Code, and CMS. Click **CMS** in the pane header.

    <Info>
      If your project doesn't have a manifest yet, the panel shows an **Initialize CMS** button. Click it to scaffold `hiveku.cms.json` with a default `blog` collection. See [Initialize Your CMS](/how-tos/initialize-cms) for details.
    </Info>
  </Step>

  <Step title="Pick a collection">
    The collection picker at the top of the panel lists every collection from the manifest. Click one to load its entries.
  </Step>
</Steps>

## The Collection Picker

The collection picker shows every collection declared in your manifest, in the order they appear there. Each row shows:

* The collection's `name`
* The number of entries (cached, refreshes on every save)
* An icon based on the format — page icon for MDX, list icon for JSON

A gear icon at the top opens the **Collection Manager** — the UI for editing the manifest itself (add, remove, or rename collections; add fields).

## The Entry List

Once you pick a collection, the panel shows the entry list:

* **Search** — full-text search across all string and markdown fields
* **Status filter** — if your collection has a `status` field with `draft`/`published` options, the filter bar shows tabs for each
* **Sort** — defaults to `defaultSort` from the manifest; click any column header to sort by it
* **Pagination** — 50 entries per page, scrollable
* **+ New entry** — opens a fresh form
* **Bulk actions** — select multiple entries with checkboxes for delete, status change, or export

For singleton collections, the list view is skipped — the form opens directly.

## The Form Editor

Click an entry to open the form editor. This is the bulk of where you'll spend time.

The form is generated from the manifest's field definitions — there's no separate form template to maintain. Each field type renders a dedicated control:

* `string` → text input or textarea
* `markdown` → split-pane editor with live preview
* `image` → drop-zone with media library picker
* `select` → dropdown
* `array` → reorderable list
* `reference` → searchable picker

See [Field Types](/cms/field-types) for the full mapping.

### Live Preview Sync

As you type, the preview pane updates in real time. The CMS panel debounces changes by \~400ms before pushing them to the preview iframe, so you get fast feedback without overwhelming the build.

<Tip>
  Live preview only works for collections with a `routePattern` — the panel needs a URL to navigate the preview to. JSON collections without a route still save fine; you just won't see the entry rendered until your code reads from the CMS.
</Tip>

### Validation

Validation runs in two passes:

1. **Client-side** — required fields, max length, regex pattern, URL syntax. Errors appear inline as you type.
2. **Server-side** — manifest-aware checks (reference target exists, slug is unique within the collection, file path is writable). Returned as a 422 with field-level error messages on save.

A red banner at the top of the form summarizes any errors. The save button stays disabled until they're resolved.

### Saving

Click **Save** (or hit `Cmd+S` / `Ctrl+S`) to write the entry to disk. Saves are atomic — either the whole entry writes or none of it does. After save:

* The entry list refreshes
* A new version is pushed to `builder_code_versions` with a snapshot of the file
* Webhooks fire (if any are configured for `entry.updated`)
* The preview iframe refreshes if it's pointed at this entry's route

There's no separate "publish" step beyond toggling a status field — content goes live with your next deploy.

## Version History

Every save creates a version. Open the version history drawer from the form's three-dot menu:

<Steps>
  <Step title="Open the menu">
    Click the three-dot icon at the top right of the form.
  </Step>

  <Step title="Open Version History">
    A drawer slides in from the right with a chronological list of versions — most recent at the top. Each version shows the saved-at timestamp and the author.
  </Step>

  <Step title="Compare or restore">
    Click any version to load it into a read-only diff view. Click **Restore this version** to bring its content back into the form. You can then edit further or save as-is.
  </Step>
</Steps>

<Warning>
  Restore brings the version's content into the form but doesn't auto-save — you still need to click **Save**. This means you can preview a restore without committing to it.
</Warning>

## Bulk Actions

Select multiple entries from the list with the checkboxes at the left. The bulk actions bar appears at the top with:

* **Delete** — removes the selected files (with confirmation)
* **Set status** — for collections with a `status` field, change all selected entries at once
* **Export** — download selected entries as JSON
* **Move** — change the slug pattern for several entries (advanced; useful for re-categorizing)

For full bulk imports from CSV/JSON, see [Bulk Import Content](/how-tos/bulk-import).

## Image and File Upload

The `image` and `file` field controls support:

* Drag-and-drop from your file system
* Paste from clipboard (image only)
* Click-to-browse
* "Choose existing" — opens the media library showing every previously-uploaded asset

Uploads go to your project's media bucket and are served through Hiveku's CDN. The file path stored in the entry is a project-relative URL like `/uploads/2026/04/hero.jpg`.

<Tip>
  Image fields with `metadata: true` capture width, height, and alt text on upload — useful for sites that need accurate `<img>` dimensions to avoid layout shift.
</Tip>

## References Picker

A `reference` field renders as a search box that opens a popup with the target collection's entries. Type to filter; click to select.

For multi-references (`multiple: true`), you can pick several entries; they show as removable chips above the picker.

The picker shows the `displayField` from the manifest if set, otherwise falls back to the entry's `title` or `name`.

## Search and Filter

The search box at the top of the entry list runs full-text search across:

* All `string` fields
* All `markdown` fields (matches body content too)
* The slug

Filters depend on the schema:

* **Status filter** — if `status` is a select with draft/published
* **Tag filter** — if `tags` is an array of strings, click any tag chip in an entry preview to filter by it
* **Date range** — if there's a date field with `defaultSort`

Search and filters compose — searching while a status filter is active narrows within the active filter.

## Keyboard Shortcuts

| Shortcut                       | Action                                   |
| ------------------------------ | ---------------------------------------- |
| `Cmd+S` / `Ctrl+S`             | Save the current entry                   |
| `Cmd+K` / `Ctrl+K`             | Open the search box                      |
| `Cmd+N` / `Ctrl+N`             | Create a new entry                       |
| `Esc`                          | Close the form, return to the entry list |
| `Cmd+Shift+H` / `Ctrl+Shift+H` | Toggle version history drawer            |

## Troubleshooting

<AccordionGroup>
  <Accordion title="The CMS panel is empty / says 'No manifest found'">
    Your project doesn't have `hiveku.cms.json` yet. Click **Initialize CMS** to scaffold it, or follow [Initialize Your CMS](/how-tos/initialize-cms).
  </Accordion>

  <Accordion title="Save returns a 422 error">
    Server-side validation failed. Check the red banner at the top of the form for the specific field and reason — common ones are missing required fields, slug conflicts with another entry, or a reference pointing at an entry that no longer exists.
  </Accordion>

  <Accordion title="Live preview doesn't update">
    The collection might not have a `routePattern`, or the preview iframe is pointed at a different page. Click the entry's slug under the form title to navigate the preview to that entry's route.
  </Accordion>

  <Accordion title="Bulk delete didn't remove from the live site">
    Saving in the CMS panel writes to the project files. Your live site only reflects the change after the next deploy. Click **Deploy** in the top bar to push.
  </Accordion>

  <Accordion title="An image won't upload">
    Check the `accept` rule on the field (some image fields restrict to specific MIME types) and your project's media quota. Images larger than 25 MB are rejected by default.
  </Accordion>

  <Accordion title="Version history is empty for an entry">
    Versions are captured per save. A brand-new entry won't have a history until you save it at least twice. The current state is implicit; the drawer shows what came before.
  </Accordion>
</AccordionGroup>

## What's Next?

<CardGroup cols={2}>
  <Card title="Bulk Import" icon="file-import" href="/how-tos/bulk-import">
    Import many entries at once from CSV or JSON
  </Card>

  <Card title="Field Types" icon="list" href="/cms/field-types">
    See every form control in detail
  </Card>

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

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