Writing and Publishing Content
Create entries, write rich content, manage drafts, and publish — from the dashboard or the API.
Once your schema is defined, you can start creating content. Airdraft has a built-in editor UI and a full REST API — use whichever fits your workflow.
Using the dashboard editor
Opening a collection
- In the sidebar, click the collection you want to write in (e.g. Posts).
- You see a list of existing entries with their status badges.
- Click New entry to create a new one.
The entry editor
The editor renders a form based on your collection's schema:
| Field type | Editor widget |
|---|---|
string |
Single-line text input |
text |
Multi-line textarea |
rich-text |
Full Tiptap editor (headings, bold/italic, links, lists, code blocks, images) |
number |
Number input |
boolean |
Toggle switch |
date / datetime |
Date/time picker |
select |
Dropdown of defined options |
media |
Media picker — opens the media library |
relation |
Search and select an entry from the referenced collection |
tags |
Tag input with comma-separated or Enter-separated tags |
Autosave
The editor autosaves a local draft every 30 seconds. Autosaved content is stored in your browser and is visible only to you — it's not committed to storage until you explicitly save.
Saving a draft
Click Save draft to persist your changes to storage with status: "draft". Drafts are not returned by default when your frontend queries published content.
Publishing
When the entry is ready to go live:
- Click Publish to set
status: "published"andpublishedAtto the current time. - The entry is immediately visible to API consumers querying published content.
To schedule a future publish, click the dropdown arrow next to Publish, set a date and time, and click Schedule. The entry will automatically transition to published at that time.
Editing an existing entry
Open the entry from the collection list. The editor loads the current published version. Any changes you make create a new revision — the previous sha is used for conflict detection.
Tip: If two people edit the same entry at the same time, the second save will fail with a conflict error. The editor shows the conflict and lets you choose which version to keep.
Deleting an entry
Open the entry and click the ⋯ menu → Delete. You must confirm deletion. Deleted entries are permanently removed (no soft delete).
Using the API
You can also manage content programmatically via the REST API or the TypeScript client.
Creating an entry
Using the server client (createCmsClient from @airdraft/next):
import { cms } from '@/lib/cms' // createCmsClient(airdraft)
const entry = await cms.createEntry('posts', {
title: 'My First Post',
excerpt: 'An introduction.',
body: '<p>Hello world!</p>',
tags: ['intro', 'hello'],
})
// entry.slug → 'my-first-post'
Using the HTTP client (AirdraftClient from @airdraft/client):
import { client } from '@/lib/client' // new AirdraftClient(...)
const result = await client.entries.create('posts', { title: 'My First Post' })
Updating an entry
Updates require the current sha (optimistic concurrency). With the server client:
const entry = await cms.getEntry('posts', 'my-first-post')
// entry.sha → content fingerprint
await cms.updateEntry('posts', 'my-first-post', {
...entry.data,
title: 'Updated Title',
}, entry.sha)
With the HTTP client:
const entry = await client.entries.get('posts', 'my-first-post')
// entry.meta.sha → sha is in meta, not top-level
await client.entries.update('posts', 'my-first-post', {
...entry.data,
title: 'Updated Title',
}, entry.meta.sha)
If the sha doesn't match (someone else edited the entry), the update throws a 409 Conflict error.
Publishing via the API
await cms.updateEntry('posts', 'my-first-post', {
...entry.data,
status: 'published',
publishedAt: new Date().toISOString(),
}, entry.sha)
Deleting an entry
// Server client
await cms.deleteEntry('posts', 'my-first-post', entry.sha)
// HTTP client
await client.entries.delete('posts', 'my-first-post', entry.meta.sha)
Entry status reference
| Status | Description |
|---|---|
draft |
Saved but not visible to public queries |
published |
Live — returned by default when querying without status filter |
scheduled |
Will automatically transition to published at publishedAt |
archived |
Manually hidden from public queries; preserves content |
Resources
@airdraft/nexton npm —createCmsClient(server-side, no HTTP)@airdraft/clienton npm —AirdraftClient(HTTP, external use)@airdraft/react-uion npm —CMSAdmin,EntryEditor- GitHub — aevrHQ/airdraft