Writing these docs · 03

Components

The callouts, steps, tabs, cards, screenshots and code blocks a page can use.

Pages are Markdown, with a few components for the things Markdown can't say. None of them need an import.

Callouts

Use sparingly: at most one per screen, 1 or 2 sentences. Each starts with its label, so the meaning never relies on colour.

<Callout type="note">Helpful context the reader can skip.</Callout>
<Callout type="keep-in-mind">Something that will surprise people if they miss it.</Callout>
<Callout type="warning">An action that can lose data, cost money or break production.</Callout>
<Callout type="plan" title="Plan: Team and Enterprise only">
  What the plan limits.
</Callout>

Fumadocs' names (info, warn, error) map onto these, so copied examples still work.

Steps

A numbered list where each step has a heading and its own paragraphs. Keep the blank lines inside each step: without them the heading and the text run together.

<Steps>
<Step>
### Create a message

Go to **Messages** and choose **Create new template**.

</Step>
<Step>
### Send a test

Choose **Send test** and enter your own email address.

</Step>
</Steps>

Create a message

Go to Messages and choose Create new template.

Send a test

Choose Send test and enter your own email address.

Tabs

For the same task in different tools or languages. Name each tab with a noun.

<Tabs items={['npm', 'pnpm']}>
  <Tab value="npm">`npm install @zymlabs/ui`</Tab>
  <Tab value="pnpm">`pnpm add @zymlabs/ui`</Tab>
</Tabs>
npm install @zymlabs/ui

Cards

Links to the next pages, with a line on each:

<Cards>
  <Card href="/docs/argon" title="Argon">
    Audiences, journeys and messages.
  </Card>
  <Card href="/docs/cloud" title="Cloud console">
    Account, workspaces, notifications.
  </Card>
</Cards>

Screenshots

A screenshot shows what words can't: a layout, where a control sits, what a result looks like. Use one where the reader needs to recognize a screen, not for every step; the steps already name each button in bold.

<Screenshot
  product="cloud-console"
  scene="members"
  alt="The Members page, listing 3 people with their roles and a pending invitation."
  caption="Optional: what the text around it doesn't already say."
/>
The Members page of Acme Inc.: 5 members with their roles, and an Invitations tab.

Each product captures its own screenshots, in light and dark, from its code with made-up data, so they stay current without anyone retaking them. A page names a scene, never a file, and shows the capture that matches the reader's theme. The scenes each product has are listed in public/screenshots/<product>/manifest.json.

  • Alt text says what the reader should see ("The Members page, listing 3 people"), not that it's a picture. Start from the scene's title in the manifest.
  • No arrows or boxes drawn on it. If something needs pointing out, say it in the text or the caption.
  • A scene that isn't there is added in the product's repository, in its list of docs scenes. Then run its docs-screenshots job and import the result:
npm run screenshots:import -- ../cloud-console/tmp/docs-screenshots/cloud-console

npm test fails if a page names a scene that doesn't exist or leaves out the alt text.

Code blocks

Code sits on blue-black in both themes, with a copy button. Set the language, and a title where the reader needs the file name. Don't include a shell prompt in commands people will copy.

```bash title="Terminal"
npm run build
```
Terminal
npm run build
lib/source.ts
import { defineDocs } from 'fumadocs-mdx/macro';

const docs = defineDocs({ dir: 'content/docs' });

Inline code, commands and IDs use backticks: NODE_AUTH_TOKEN.

Tables

Markdown tables, with the first row as the header. Keep cells to a line; a table that needs paragraphs wants to be a list.

KindLabelWhen
noteNote:Context the reader can skip.
keep-in-mindKeep in mind:A surprise if missed.
warningWarning:Loses data, costs money, breaks prod.
planPlan:Limited to certain plans.

What's next

On this page