Skip to content

Authoring reference

This page is .mdx. Components only work in .mdx; a .md file renders the import line as text. Asides, code blocks and Expressive Code work in both.

Four types, no more. The title in brackets is optional — without it you get the type name.

:::note[Custom title]
Body.
:::

Wraps an ordered list. Use it for every Getting started page — it makes a procedure read as a procedure rather than as a list of sentences.

  1. Open the project you want to rig.

  2. Switch to Mocap and pick your camera.

    Steps can hold several paragraphs, code blocks and images — anything indented under the number stays in that step.

    Terminal window
    koi doctor --camera
  3. Check the character follows your head.

Platform splits, without splitting the page. Give every tab set the same syncKey and choosing Windows once chooses it everywhere on the page.

Installs to %LOCALAPPDATA%\CoyKoi.

Card

A block of highlighted content. Icons are optional.

Another

<CardGrid> lays them out; add stagger to offset the second column.

Link button

Inline labels: New Pro only Deprecated

Also available in frontmatter, which is what puts “Internal” beside this page in the sidebar:

sidebar:
badge: Internal
  • Directorysrc
    • Directorycontent
      • Directorydocs
        • Directorystudio
          • index.md the introduction
          • Directorygetting-started/
            • …
      • Directoryshared/ written once, rendered into every app
        • …
  • astro.config.mjs

Starlight’s set is listed in its own docs. The names are also what src/editions.ts uses for each app.

Expressive Code is on, so blocks do more than highlight. A title turns it into a framed file; a bash block with no title becomes a terminal frame.

src/editions.ts
export const EDITIONS = [
{ id: 'studio', label: 'Studio' },
{ id: 'prop', label: 'Prop' },
{ id: 'stream', label: 'Stream' },
{ id: 'legacy', label: 'Legacy' },
];

That block uses, in order: title= for the frame, {3} to mark a line, ins=/del= for added and removed lines, and "EDITION_IDS" to highlight every occurrence of a string.

Also available: showLineNumbers, startLineNumber=, collapse={4-10} to fold a range, and frame="none" to drop the chrome.

Two ways, for two jobs.

D2 for architecture — written as a fenced d2 block, rendered to SVG at build time. Works in .md as well as .mdx.

Diagram

The diagram components for figurative explanation — the monoline set in src/components/diagram/.

CaptureperformerSolvemotion curvesRetargetyour character
The motif set lives in src/components/diagram/.

Only in src/content/shared/, and only in .mdx.

This paragraph renders under /studio/ and nowhere else. On this page it always shows, because this page is not shared.

<EditionOnly is={['prop', 'stream']}>
Shown under Prop and Stream, not Studio.
</EditionOnly>
---
title: Install Studio # required
description: One sentence. # feeds search and social cards
sidebar:
order: 2 # lower floats higher; ties fall back to alphabetical
label: Install # shorter nav text than the title
badge: New
hidden: false # keep the URL, drop it from the nav
draft: false # shows a notice; does NOT exclude from the build
layout: cards # this project's own: drops the sidebars, steps through sections
---
  1. Components need .mdx. A .md file prints the import line verbatim.

  2. Shared pages should stay plain. Anything in src/content/shared/ is read by the Flutter app as raw, unprocessed markdown — components arrive there as literal tags. Keep them to markdown plus <EditionOnly>.

  3. A new shared page needs a SHARED_NAV entry in src/editions.ts, or it builds and is reachable but never appears in a sidebar. App-specific pages under src/content/docs/<app>/ are picked up automatically.

  4. sidebar.order does nothing on shared pages. They are ordered by their position in the SHARED_NAV array.

  5. draft: true still ships. It adds a notice; it does not remove the page from a production build.

  6. d2 needs the binary. No d2 on PATH and diagrams silently do not render — no error, just nothing.

  7. Don’t run astro build while astro dev is up. They share the .astro/ content cache, and a build leaves the dev server serving stale pages until you restart it.