Writing Content
MDX components, conventions, and the editorial rules that keep the collection readable.
Whitepapers are written in MDX — Markdown with embedded React components. This page covers the components available, the editorial conventions, and a few gotchas.
Components at your disposal
Every MDX file can import from fumadocs-ui/components/*. The components most useful for whitepapers:
| Component | When to use |
|---|---|
Callout | Asides, warnings, footnotes that don't belong in flow |
Tabs / Tab | When the same concept has language- or platform-specific forms |
Steps / Step | Tutorial-style sequences |
Accordions / Accordion | Optional detail that most readers should skip |
TypeTable | API reference tables — types, defaults, descriptions |
Files / Folder / File | Directory trees |
Callout
import { Callout } from "fumadocs-ui/components/callout";
<Callout type="info" title="Heads up">
Body text goes here. Markdown works inside.
</Callout>Types: info, warn, error, success. Default is info.
Example
This is what an info callout looks like rendered.
Example
This is what a warn callout looks like rendered.
Tabs
Use when the same instruction has variants. Don't overuse — three tabs is fine, eight is a sign you need a different structure.
bash npm install fumadocs-ui bash pnpm add fumadocs-ui bash yarn add fumadocs-ui Code blocks
Triple-backtick fences with a language identifier get syntax highlighting. Add a title for files:
```ts title="lib/source.ts"
import { docs } from "collections/server";
import { loader } from "fumadocs-core/source";
export const source = loader({
baseUrl: "/docs",
source: docs.toFumadocsSource(),
});
```Supported languages: TypeScript, JavaScript, Python, Go, Rust, SQL, Bash, JSON, YAML, and most others Shiki recognizes.
Editorial conventions
A few rules that keep the library readable as it grows.
Headings
##for top-level sections. Aim for 4–8 per paper.###for sub-sections. Optional; use only when a section has genuinely distinct sub-claims.- Never
####or below. If you need that depth, the section is too long.
Length
- Abstract: 100–200 words
- Section: 200–600 words
- Whole paper: 3,000–8,000 words
Papers shorter than 3,000 words usually belong as blog posts. Papers longer than 8,000 should be split into a series.
Citations
Link directly to the primary source — the paper, the spec, the original blog post. Summary articles age poorly and the links rot. Use the References section at the end for formal citations.
Tone
Direct, specific, quantitative where possible. Avoid:
- Hedging adjectives ("significantly", "substantially") without numbers
- Marketing-speak ("seamless", "robust", "powerful")
- Rhetorical questions in body prose (they read as filler)
The first paragraph is the only one some readers will see
Search snippets, social previews, and skim-readers all anchor on the opening. Treat it as the abstract: state the claim, name the evidence, hint at the conclusion.
Common pitfalls
A few things that trip up new contributors:
- Duplicate
# Title— frontmattertitlealready renders the h1. Don't repeat it in the body. - Stale
.source/— if a new file doesn't appear in the sidebar, delete.source/and restartnpm run dev. - Bad relative links — links in MDX use the URL, not the file path.
/docs/security/foonot../security/foo.mdx. - Tabs/Steps imported wrong —
import { Tab, Tabs } from 'fumadocs-ui/components/tabs'— both, plural for the wrapper.
How is this guide?