Writing Content
Docs are written in the MDX format, which is just markdown with components. Markdown files can also be used, but using MDX is strongly encouraged.
Frontmatter
Every file can have a YAML frontmatter block at the top:
---
title: My Page Title
description: A short summary shown in search results.
---| Field | Purpose |
|---|---|
title | Page title shown in the browser tab and sidebar. Defaults to the first H1. |
description | Meta description for search engines, also shown under the page title. |
Page order comes from docs.config.json's sidebar (see Configuration Reference), or alphabetically by filename if you don't define one.
Headings
Use # for the page title (H1) and ##/### for sections. Only one H1 per page.
# Page Title
## Section
### SubsectionLinks
To another doc in your project:
[Getting Started](./getting-started.mdx)
[See the FAQ](./reference/faq.mdx)Use relative paths including the .mdx extension - the link resolver matches on file path, not URL slug.
To an external URL:
[GitHub](https://github.com/TrickfireRobotics)Images
Place images in docs/assets/ and reference them relatively:
SVG files work the same way.
To constrain an image's size, wrap it in the global Image component rather than sizing it
yourself - it centers by default and accepts a width:
<Image width="50%"></Image>width- any CSS width ("50%","300px") or a bare number, treated as pixels.center- defaults totrue; passcenter={false}to left-align instead.
Always pass the image as markdown syntax inside <Image>, not as an src prop - only the
markdown form goes through the pipeline that resolves and optimizes the file.
Code blocks
Fenced code blocks with a language tag get syntax highlighting:
```python
import can
bus = can.Bus(interface='socketcan', channel='can0')
msg = can.Message(arbitration_id=0x123, data=[0x01, 0x02])
bus.send(msg)
```Supported language tags include python, typescript, bash, yaml, json, c, cpp, and many more.
Show a filename:
```python title="examples/send_message.py"
# ...
```Highlight specific lines, using a [!code highlight] comment on the line:
```python
import can
bus = can.Bus(...)
msg = can.Message(...)
bus.send(msg)
```Admonitions
Callout boxes for notes, warnings, and tips. Callout is available globally - no import needed:
<Callout type="info" title="Note">
Extra context that's useful but not critical.
</Callout>
<Callout type="idea" title="Tip">
A recommended shortcut or best practice.
</Callout>
<Callout type="warning" title="Warning">
Something that can break things if ignored.
</Callout>
<Callout type="error" title="Danger">
Do not do this - data loss or hardware damage possible.
</Callout>type is one of info, idea, warning, error, or success. title is optional.
Tables
| Column A | Column B | Column C |
| -------- | -------- | -------- |
| Row 1 | Value | Value |
| Row 2 | Value | Value |Column alignment with :---, :---:, and ---: for left, center, and right.
Tabs
Show alternative instructions for different environments. Tab/Tabs are available globally,
like Callout - no import needed (content repos don't have fumadocs-ui installed, so a local
import ... from "fumadocs-ui/components/tabs" would fail to resolve for anything outside this
repo's own docs/):
<Tabs items={["Linux", "macOS"]}>
<Tab value="Linux">Install with apt: `sudo apt install can-utils`</Tab>
<Tab value="macOS">Install with brew: `brew install can-utils`</Tab>
</Tabs>Steps
Numbered setup instructions. Also global, no import needed:
<Steps>
<Step>Install the CAN utilities: `sudo apt install can-utils`.</Step>
<Step>Bring the interface up: `sudo ip link set can0 up type can bitrate 500000`.</Step>
<Step>Verify it's listening: `candump can0`.</Step>
</Steps>Toggle sections
Collapsible sections - good for troubleshooting entries, FAQs, or anything else that shouldn't all be expanded at once. Also global, no import needed:
<Accordions>
<Accordion title="candump shows no traffic">
Check the interface is up (`ip link show can0`) and the bitrate matches the bus.
</Accordion>
<Accordion title="Bus errors under load">
Usually a termination resistor problem - verify both ends of the bus are terminated at 120Ω.
</Accordion>
</Accordions>By default only one item can be open at a time. Add multiple to Accordions to allow several open at once.
File organization
If docs.config.json doesn't define a sidebar, pages are listed alphabetically by filename with no grouping:
docs/
├── getting-started.mdx
├── guides/
│ ├── installation.mdx
│ └── configuration.mdx
└── reference/
├── api.mdx
└── faq.mdxFor custom ordering, labels, icons, or grouped categories, define sidebar explicitly - see Configuration Reference.