Writing Documentation
Learn how to write and structure documentation using MDX
This guide covers the technical aspects of writing documentation for zero-sources using MDX (Markdown + JSX).
Documentation Structure
Our documentation lives in the apps/docs/content/docs/ directory:
content/docs/
├── getting-started/ # Quick start guides
├── guides/ # How-to guides
├── packages/ # Library documentation
├── change-sources/ # Change source docs
├── architecture/ # System design
├── api/ # API reference
└── contributing/ # This sectionMDX Basics
MDX allows you to use JSX components in Markdown:
---
title: My Page
description: Page description for SEO
---
# My Page Title
Regular **markdown** content with [links](/other-page).
<Callout type="info">
A custom React component!
</Callout>
```typescript
// Code blocks work normally
const example = "Hello";
```Frontmatter
Every MDX file must start with frontmatter:
---
title: Page Title # Required - shown in nav and browser
description: Brief page description # Required - used for SEO and previews
icon: IconName # Optional - icon for navigation
---Available Icons
Common icons you can use:
Book- Guides and tutorialsCode- API and code referenceRocket- Getting startedPackage- Library documentationSettings- ConfigurationHeart- Community and contributingFilePen- Writing and editing
Custom Components
Callouts
Highlight important information:
<Callout type="info">
**Note**: This is informational content.
</Callout>
<Callout type="warning">
**Warning**: This requires caution.
</Callout>
<Callout type="error">
**Error**: This is critical information.
</Callout>
<Callout type="success">
**Success**: This is a positive message.
</Callout>Result:
Note: This is informational content.
Cards
Create card layouts for links:
<Cards>
<Card
title="Getting Started"
href="/getting-started"
description="Quick start guide"
/>
<Card
title="API Reference"
href="/api"
description="Complete API docs"
/>
</Cards>Result:
Tabs
Create tabbed content:
<Tabs items={['TypeScript', 'JavaScript']}>
<Tab value="TypeScript">
```typescript
const typed: string = "Hello";
```
</Tab>
<Tab value="JavaScript">
```javascript
const untyped = "Hello";
```
</Tab>
</Tabs>Result:
TypeScript:
const typed: string = "Hello";JavaScript:
const untyped = "Hello";Steps
Create numbered step-by-step guides:
<Steps>
### Install dependencies
```bash
pnpm install
```
### Configure environment
Create a `.env` file with your settings.
### Start development
```bash
pnpm dev
```
</Steps>Result:
1. Install dependencies
pnpm install2. Configure environment
Create a .env file with your settings.
3. Start development
pnpm devCode Blocks
Basic Code Blocks
Use triple backticks with language specification:
```typescript
const example: string = "Hello";
```Supported languages:
typescript/tsjavascript/jsjsx/tsxbash/shjsonyaml/ymlmarkdown/mdcsshtml
Inline Code
Use backticks for inline code:
Use the `useZero()` hook to access the Zero instance.Result: Use the useZero() hook to access the Zero instance.
Code with Line Numbers
Long code blocks automatically get line numbers:
// This is a longer example
import { Zero } from '@rocicorp/zero';
import { schema } from './schema';
const zero = new Zero({
server: process.env.ZERO_SERVER_URL,
schema,
userID: 'user-123',
});
const messages = zero.query.message
.where('roomId', '=', roomId)
.orderBy('createdAt', 'desc');Links and References
Internal Links
Link to other documentation pages:
See the [getting started guide](/getting-started) for setup instructions.
Learn about [change sources](/change-sources/mongodb).External Links
Link to external resources:
Built with [Fumadocs](https://fumadocs.vercel.app/).
View on [GitHub](https://github.com/cbnsndwch/zero-sources).Anchor Links
Link to headings within a page:
See [Installation](#installation) below.
Jump to [Advanced Topics](#advanced-topics).Images and Media
Images
Add images to apps/docs/public/:
Guidelines for Images
- Use descriptive alt text
- Keep file sizes reasonable (under 200KB)
- Use PNG for screenshots, SVG for diagrams
- Name files descriptively:
change-source-diagram.png
Tables
Create tables with pipe syntax:
| Parameter | Type | Required | Description |
|-----------|--------|----------|------------------|
| id | string | Yes | Unique identifier|
| name | string | No | Display name |Result:
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | string | Yes | Unique identifier |
| name | string | No | Display name |
Lists
Unordered Lists
- Item 1
- Item 2
- Nested item
- Another nested item
- Item 3Ordered Lists
1. First step
2. Second step
3. Third stepTask Lists
- [x] Completed task
- [ ] Incomplete task
- [ ] Another taskFormatting
Text Formatting
**Bold text** for emphasis
*Italic text* for subtle emphasis
`Inline code` for code elements
~~Strikethrough~~ for deprecated contentBlockquotes
> This is a blockquote.
> It can span multiple lines.Navigation
Adding New Pages
- Create your MDX file in the appropriate directory
- Update
meta.jsonin that directory (if it exists) - Link to your page from related pages
meta.json
Control navigation order and labels:
{
"title": "Section Title",
"pages": [
"getting-started",
"installation",
"configuration"
]
}Templates
Use our templates as starting points:
Library Template
For documenting packages
Guide Template
For how-to guides
API Template
For API reference
Testing Your Changes
Local Development
# Start the docs server
pnpm --filter docs dev
# Visit http://localhost:3000Check for Issues
- Preview in browser
- Test all links
- Verify code examples
- Check mobile view
- Run linter:
pnpm --filter docs lint
Common Patterns
API Documentation
## `functionName(param: Type): ReturnType`
Description of the function.
**Parameters:**
- `param` (`Type`) - Parameter description
**Returns:**
`ReturnType` - Return value description
**Example:**
```typescript
const result = functionName('value');
### Configuration Options
```markdown
### `optionName`
- **Type**: `string`
- **Required**: Yes
- **Default**: `'default-value'`
Description of the option.
**Example:**
```typescript
{
optionName: 'value'
}
### Step-by-Step Instructions
Use the `<Steps>` component for sequential instructions:
```mdx
<Steps>
### Step 1: First action
Do this first.
### Step 2: Next action
Then do this.
</Steps>Best Practices
Writing
- Be clear and concise - Get to the point
- Use examples - Show, don't just tell
- Be consistent - Follow established patterns
- Test your examples - Make sure code works
Structure
- Use headings properly - Maintain hierarchy (H1 → H2 → H3)
- Break up content - Use lists, callouts, and spacing
- Add navigation - Link to related content
- Include context - Don't assume prior knowledge
Code Examples
- Keep them short - Focus on relevant parts
- Include types - Show TypeScript types when helpful
- Add comments - Explain non-obvious parts
- Show imports - Include necessary imports
Troubleshooting
MDX Parsing Errors
If you see parsing errors:
- Check frontmatter syntax
- Ensure all JSX tags are closed
- Verify backticks in code blocks
- Check for unescaped special characters
Components Not Working
If custom components don't render:
- Check component name spelling
- Verify all required props are provided
- Ensure proper JSX syntax
- Check component is imported/available
Links Not Working
If links are broken:
- Use absolute paths from docs root:
/getting-started - Check file exists at target location
- Verify URL in navigation matches filename
- Test links in local development
Resources
Style Guide
Content and formatting standards
Contributing Guide
How to contribute
Fumadocs Docs
Framework documentation
MDX Docs
MDX specification
Getting Help
- Questions: GitHub Discussions
- Issues: GitHub Issues
- Examples: Look at existing documentation pages
Ready to write? Check out our templates or contribute!
How was this page?