Authoring docs
Edit and extend the Convoy docs site — where content lives, how the sidebar is configured, and what stays in sync with code.
The public docs site lives under apps/docs/. Content is MDX under
apps/docs/content/docs/. This page documents the site's conventions
so a contributor can make edits with confidence and without breaking
the sidebar.
Where content lives
apps/docs/content/docs/
├── meta.json # Root sidebar configuration
├── index.mdx # /docs (landing)
├── <section>/
│ ├── meta.json # Optional per-folder config
│ ├── index.mdx # /docs/<section>
│ └── <page>.mdx # /docs/<section>/<page>Each .mdx file becomes one page. Every folder can have a meta.json
to control its title and its page ordering.
Local development
From the repo root:
pnpm docs:dev # https://docs.convoy.localhost
pnpm docs:types:check # Typegen + MDX + tsc --noEmit
pnpm docs:build # Production build
pnpm docs:lint # BiomeRun types:check, build, and lint before opening a PR. Biome is
strict about JSON formatting — small meta.json pages arrays must
be on a single line; multi-line arrays for longer lists.
meta.json basics
{
"title": "Section title",
"description": "Shown under the title.",
"defaultOpen": false,
"collapsible": true,
"pages": ["index", "first-page", "second-page"]
}| Field | Purpose |
|---|---|
title | Sidebar label. |
description | Optional, mostly informational. |
defaultOpen | Initial-load state for collapsible folders. Set to false so readers see a compact sidebar; the folder containing the active page auto-expands anyway. |
collapsible | Whether the folder collapses at all. |
pages | Explicit page ordering. Use "<name>" for a file, "<folder>" for a nested folder, and "---[icon]Label---" for a section separator. |
The root-meta flattening gotcha
This one trips people up.
The root apps/docs/content/docs/meta.json uses separators to
define the visible sidebar sections (Getting started, Deploy Convoy,
CLI & AI integrations, etc.). For most sections, root meta lists each
page individually — e.g.
"---[terminal]CLI & AI integrations---",
"cli/index",
"cli/api-keys",
"cli/install",When root meta lists a page path explicitly, root owns that page at
priority 2. A folder-level meta.json inside cli/ would try to claim
the same pages, but root has already claimed them, so the folder's
pages ordering is ignored for the sidebar.
Practical rule:
- To add or reorder pages in a flat section (Using Convoy,
Operations, Contributing, Reference), edit the root
meta.json. The section's ownmeta.jsonis used only for the folder's title in nested contexts. - To add or reorder pages in a collapsible sub-folder (e.g.
cli/mcp/,cli/dev-container/), edit that folder'smeta.json. Root lists the folder path (cli/mcp), not its children, so the folder's meta is authoritative.
If you add a new page and it doesn't appear in the sidebar, check whether root meta needs a new entry.
Section separators and icons
Root meta uses the ---[icon]Name--- syntax to draw visual separators
for top-level sections. Available icons are registered in
apps/docs/app/lib/source.ts:
const iconMap: Record<string, LucideIcon> = {
"book-open": BookOpen,
code: Code,
compass: Compass,
"layout-grid": LayoutGrid,
rocket: Rocket,
sparkles: Sparkles,
terminal: Terminal,
wrench: Wrench,
};To use a new icon, import it from lucide-react and add it to the map
with a stable kebab-case key. Separators without an icon still render;
they just don't carry a glyph.
MDX components available in pages
The default Fumadocs MDX components are registered in
apps/docs/app/components/mdx.tsx. Notable additions:
<Cards>/<Card title="…" description="…" href="…" />— used on the landing to surface audience paths.<Mermaid chart={…} />— for sequence and flowchart diagrams. Preferred over ASCII art when the diagram has more than three nodes.- Standard markdown: tables, code fences (including
language-mermaidblocks, which render the same as the component),<kbd>keys.
What stays in sync with code
A few docs pages mirror specific code modules. Whenever you change the code, update the page in the same PR — otherwise readers get a misleading reference.
| Page | Source of truth |
|---|---|
using/keyboard-shortcuts.mdx | SHORTCUT_GROUPS in apps/web/components/blocks/sidebar/keyboard-shortcuts-dialog.tsx and the key literals in apps/web/lib/browser/hotkeys.ts. |
reference/mcp-tools.mdx | getToolDefinitions() in apps/web/convex/mcp/tools.ts. |
reference/config-toml.mdx | ConfigFileSchema in apps/cli/src/lib/config/types.ts and the profile resolver in profile.ts. |
contributing/cli-architecture-and-lifecycle.mdx | cliNormalizedEventValidator in apps/web/convex/lib/contracts/validators.ts and the runtime files under apps/web/convex/cli/lib/runtimes/. |
reference/cli-commands.mdx | The commander definitions under apps/cli/src/commands/ (and addGlobalOptions in apps/cli/src/cli.ts). |
reference/roadmap.mdx | CLI_RUNTIME_SLUGS in apps/web/convex/cli/lib/runtimes/contracts.ts and the CLI-side runners under apps/cli/src/agent/runtimes/. Promote a runtime from "config only" to "supported" when the CLI-side runner lands. |
reference/glossary.mdx | Domain concepts introduced in the spec. Add an entry when a new term enters the product vocabulary. |
Section landings
The convention for landing pages (<section>/index.mdx) is:
- Short intro paragraph.
- One or two context sections if needed (what this section covers, how it relates to the rest of the docs).
- End with a
## Next stepspointer list — 3–6 links, each with a one-phrase rationale.
Exceptions: landings whose whole body is already the pointer list (the Reference index, the Operations index) skip the separate "Next steps" block to avoid duplication.
Deploying the docs
The docs site is a static build. See
Deploy the Docs Site for the
hosting setup.
See also
- Contributing overview — repository map and conventions
- Specs-first workflow