Documentation System
This project uses Nextra to power the /docs experience with MDX content and the docs theme.
Features
📚 MDX-Based Content
Write documentation in MDX (Markdown + JSX) with support for:
- Rich markdown syntax with GitHub Flavored Markdown (GFM)
- React components embedded directly in your docs
- Code syntax highlighting with Shiki
- Frontmatter metadata for titles, descriptions, and more
🎨 Beautiful UI
Built with Nextra theme:
- Responsive sidebar navigation with collapsible sections
- Table of contents for easy navigation within pages
- Previous/Next navigation between pages
- Full-text search functionality
- Clean, professional design
🚀 Developer Experience
Optimized for productivity:
- Hot reload - see changes instantly during development
- Type-safe - full TypeScript support
- Fast builds - optimized for Cloudflare Workers with OpenNext
- Git-based - version control your docs alongside code
Directory Structure
Documentation content is organized in the src/app/en/docs/ directory:
src/app/en/docs/
├── layout.tsx # Bind the shared Nextra docs shell
├── (overview)/
│ └── page.mdx # Documentation home page
├── _meta.js # Root navigation configuration
├── getting-started/
│ ├── _meta.js # Section navigation
│ ├── installation/
│ │ └── page.mdx
│ ├── configuration/
│ │ └── page.mdx
│ └── deployment/
│ └── page.mdx
└── guides/
├── _meta.js
├── authentication/
│ └── page.mdx
├── blog-system/
│ └── page.mdx
└── documentation/
└── page.mdxKeep this tree user-facing. Store internal contributor guidance in route-local AGENTS.md files and follow docs/AGENTS.md for maintainer documentation placement.
Creating Documentation
Add a New Page
- Create a new folder and
page.mdxfile in the appropriate directory:
mkdir -p src/app/en/docs/guides/my-guide
touch src/app/en/docs/guides/my-guide/page.mdx- Add frontmatter and content:
---
locale: en
translationKey: guides.my-guide
title: My Guide
description: A helpful guide about something
---
# My Guide
Your content here with **markdown** formatting!
## Sections
Use headers to organize your content.- Update the
_meta.jsfile in the parent directory:
export default {
authentication: "Authentication",
"blog-system": "Blog System",
"my-guide": "My Guide",
};Add a New Section
- Create a new directory:
mkdir -p src/app/en/docs/my-section/page-1
mkdir -p src/app/en/docs/my-section/page-2- Create
_meta.jsfor navigation:
export default {
"page-1": "Page 1",
"page-2": "Page 2",
};- Add pages to the section:
touch src/app/en/docs/my-section/page-1/page.mdx
touch src/app/en/docs/my-section/page-2/page.mdxFrontmatter Options
Each MDX file should include frontmatter at the top:
---
locale: en
translationKey: guides.my-guide
title: Page Title
description: Brief description for SEO and previews
---Available Fields
- title (required) - Page title shown in navigation and header
- description (required for published language resources) - Meta description for SEO
- locale (required) - Resource language,
enorzh-CN - translationKey (required) - Shared topic identity for complete equivalent versions
Markdown Features
Code Blocks
With syntax highlighting:
```tsx
import { Button } from "@t3template/ui/button";
export function Example() {
return <Button>Click me</Button>;
}
```Links
Link to other documentation pages:
See also: [Authentication Guide](/en/docs/guides/authentication)Tables
Create data tables:
| Feature | Description |
| ------- | ------------------- |
| MDX | Markdown with JSX |
| Search | Full-text search |
| Theme | Customizable design |Lists
Ordered and unordered lists:
- Item 1
- Item 2
- Nested item
- Another nested item
1. First step
2. Second step
3. Third stepImages
Add images to your docs:
Blockquotes
Highlight important information:
> **Note:** This is an important note that readers should pay attention to.Configuration
Customize Theme
Edit theme.config.tsx in the project root:
import { Footer, Navbar } from "nextra-theme-docs";
const docsThemeConfig = {
navbar: (
<Navbar
logo={<span>Your Docs Logo</span>}
logoLink="/en/docs"
projectLink="https://github.com/aigotowork/cfstack"
/>
),
footer: <Footer>Your Footer Text</Footer>,
docsRepositoryBase: "https://github.com/aigotowork/cfstack/tree/main/src/app",
};Navigation Structure
The sidebar navigation is automatically generated from:
- Your file structure in
src/app/en/docs/ - The
_meta.jsfiles in each directory
Example _meta.js:
export default {
index: "Introduction",
"getting-started": "Getting Started",
guides: "Guides",
"api-reference": "API Reference",
};Styling
Custom Styles
Add custom styles to src/styles/docs-custom.css:
/* Custom documentation styles */
.nextra-content {
/* Your custom styles */
}Theme Colors
The docs inherit your global theme colors from src/styles/globals.css.
Best Practices
1. Organize by Feature
Group related documentation together in folders.
2. Use Clear Titles
Make titles descriptive and scannable:
- ✅ “Installing Dependencies”
- ❌ “Installation”
3. Add Examples
Include code examples for every concept.
4. Link Between Pages
Use relative links to connect related documentation:
See also: [Configuration Guide](/en/docs/getting-started/configuration)5. Keep It Updated
Review and update documentation regularly:
- When you add new features
- When APIs change
- When users report confusion
Troubleshooting
MDX Compilation Errors
If you see MDX errors:
- Check for unclosed JSX tags
- Ensure proper frontmatter formatting (YAML syntax)
- Verify code blocks use proper triple backticks
Navigation Not Updating
If sidebar navigation doesn’t reflect your changes:
- Restart the dev server
- Check
_meta.jsfiles for syntax errors - Clear Next.js cache:
rm -rf .next
Styling Issues
If styles aren’t applying:
- Verify CSS imports in the shared
src/app/docs/reading-layout.tsx - Check Tailwind config
- Restart dev server after config changes
Next Steps
- Write your first documentation page
- Customize the theme configuration
- Add custom components for your docs
Resources
Language resources and search
English resources now live in src/app/en/docs; Chinese resources live in src/app/zh-CN/docs. The original /docs entry redirects known pages to English. Both trees share src/app/docs/reading-layout.tsx, the Nextra MDX component registry and the site header. Every published page declares locale, translationKey, title and description in frontmatter. Use the same translation key for equivalent complete versions and provide local _meta.js labels and links.
Keep unpublished Docs outside the public App Router tree: the build rejects draft: true in a public page.mdx instead of silently publishing it. Missing translations are an explicit noindex reading-link screen and do not enter the sitemap or search index.
The root resolves language per request, so production Docs pages are dynamic. npm run build runs scripts/docs-search.ts through postbuild to create Pagefind records directly from authored resources, using the installed MDX parser. It omits code, imports, executable expressions and component attributes; it does not evaluate MDX during indexing. Pagefind owns language tokenization and Nextra owns the search UI. Search reads only the current language index/filter and uses canonical language URLs. No Worker filesystem scan or live content indexing is required.