The authoring model¶
A few rules are the same across every content type. Learn them here so each how-to page can stay short.
1. Parent + translations¶
Most content is split into a parent and one translation per language:
- The parent holds the things that don't change between languages — the
slug, the category, the tier (free/premium), the program week, etc. - Each translation holds the language-specific text — title, body copy, "why this works", transcript, and so on.
You author the parent once, then add a translation for each language.
Languages:
- English (
en) — required for everything. - German (
de) — required for anything shown to users (German is live). - Spanish (
es) — optional; may be left empty.
2. Status: draft → review → published¶
Every translation has a status:
- draft — work in progress. The app never shows it.
- review — ready for a second pair of eyes. The app never shows it.
- published — live. The app only ever shows
publishedcontent.
A parent with only draft/review translations is invisible in the app. A piece of
content "goes live" the moment its translation is set to published (per
language — you can publish English while German is still in draft).

3. Slugs are permanent once published¶
The slug is the content's stable identifier (e.g. body-scan-standard). It's
how the app, deep links, and other content (like a Coach card) point at this row.
You cannot rename a slug while any translation is published. The system
blocks the save with an error listing the published languages. If you genuinely
must rename: set every translation back to draft, rename, then republish.
Renaming a live slug would break deep links and cached references — that's why
it's gated.
Renaming a published slug
The save is blocked by the slug-rename-translation-guard. The error
modal lists the affected published locale(s); there is no override.
To rename: set every translation back to draft, rename, republish.
4. The system checks your work on save¶
When you save, Directus runs validation and will block the save with a plain error modal if something is wrong — before anything reaches the app. This is a safety net, not a nuisance: it catches typos that would otherwise show up as a broken card or a missing session in the app. Examples of what it catches:
- A Coach card pointing at a session slug / sound that doesn't exist.
- A session's structured content not matching its template type.
- A navigation link pointing at a screen that isn't real.
Each how-to page notes the specific rules for that type. If you hit an error you don't understand, copy it and ask in the team channel — the message names the exact field.
See the Content-block reference for the exact fields and allowed values of every block the validator checks, and Composition & sequence rules for the conversation-flow rules.
5. Images and audio (assets)¶
Images (session/album artwork) and audio (voice tracks, sound files) are assets. You upload or attach them in Directus; the system automatically mirrors them to Naluma's media storage (R2) and the app streams them from there. You don't manage storage — just attach the right file to the right field. An asset that doesn't resolve will block publishing.
Most "auto" content like generated audio for the dummy/test data is produced by a developer tool, not authored by hand. As an editor you mainly attach the image and audio files and write the text.