Vite plugin that generates typed navigation trees from MDX content colocated with your TanStack Router routes.
Colocates MDX documentation with TanStack Router routes following the same file-system conventions. _meta.json files provide display names and ordering per directory. The plugin scans the structure and outputs a typed tree and page map for use in navigation components.
bun add @rodavel/tanstack-mdx-tree// vite.config.ts
import { contentTreeGeneratorPlugin } from "@rodavel/tanstack-mdx-tree";
export default defineConfig({
plugins: [
contentTreeGeneratorPlugin({
docsDir: "src/routes/docs",
outFile: "src/generated/docs-tree.gen.ts",
}),
],
});The plugin scans docsDir for page files (default index.mdx) with YAML frontmatter, builds a nested navigation tree, and writes it to outFile as a TypeScript module. It regenerates on every content or metadata change during dev.
The URL prefix is derived from docsDir relative to routesDir (default src/routes). For example, src/routes/docs produces the prefix /docs, so a page at src/routes/docs/guides/index.mdx gets the URL /docs/guides.
The root tree node name comes from the root _meta.json file's name field. If no root _meta.json exists, the directory name is used (e.g., docs).
src/routes/docs/
├── _meta.json # { "name": "Documentation" }
├── index.mdx # Root page → becomes tree.index
├── guides/
│ ├── _meta.json # { "name": "Guides", "order": 1 }
│ ├── index.mdx
│ └── setup/
│ └── index.mdx
└── api/
├── _meta.json # { "name": "API Reference", "order": 2 }
└── index.mdx
Each directory can contain a _meta.json file to configure its tree node:
| Field | Type | Description |
|---|---|---|
name |
string |
Display label for the directory node |
order |
number |
Sort order (lower values appear first) |
Any additional fields are passed through as extra on the DirectoryMeta object:
{
"name": "Guides",
"order": 1,
"icon": "book"
}Here icon would be available as extra.icon.
| Option | Type | Description |
|---|---|---|
docsDir |
string |
Path to the content directory to scan |
outFile |
string |
Path where the generated TypeScript file is written |
| Option | Type | Default | Description |
|---|---|---|---|
routesDir |
string |
"src/routes" |
TanStack Router routes directory, used to derive the URL prefix |
metaFile |
string |
"_meta.json" |
Filename for directory metadata |
pageFile |
string |
"index.mdx" |
Filename to match as a page entry |
enrichPages |
(pages, pageByKey) => void |
no-op | Callback invoked after scanning and before tree building; mutate pages in place (e.g., inherit fields from ancestors). Receives the pages array and a Map<string, ScannedPage> for O(1) lookups |
Generate the content tree from the command line using your existing Vite config:
npx content-treeThe CLI reads the contentTreeGeneratorPlugin options from your vite.config.ts and runs the generator. Useful for CI or scripts that need to generate the tree outside of a Vite build.
- Vite 5+
- Node.js 18+