Skip to content

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 published content.

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

Status field: draft / review / published

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.