Migrate documentation site to Fumadocs with monorepo structure and shared content#11
Migrate documentation site to Fumadocs with monorepo structure and shared content#11
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Co-authored-by: huangyiirene <7665279+huangyiirene@users.noreply.github.com>
…rver Co-authored-by: huangyiirene <7665279+huangyiirene@users.noreply.github.com>
|
@copilot nextjs项目使用多包架构放到apps/docs,不要污染根目录 |
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Done! The Next.js documentation site has been moved to Changes:
See commit 3124fe9 for the complete restructuring. |
|
@copilot 我的文档还是放在很目录,不要换位置 /content/docs |
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Done! Documentation content is now kept at the root directory Changes:
The Next.js app remains in See commit c60ebe7 for the changes. |
…mprove documentation formatting, and refine build scripts
… prevent H1 generation in new files
… hero section, and implement feature cards
Moved reference .mdx files into protocol-based subdirectories (data, ui, system, ai, misc) and added meta.json files for each category. Updated build-docs.ts to generate documentation into these new directories and to update meta.json for navigation. This improves organization and navigation of API reference documentation.
There was a problem hiding this comment.
Pull request overview
This PR migrates the documentation site from a custom @objectdocs/cli tooling to Fumadocs, a modern Next.js-based documentation framework, while restructuring the repository into a proper monorepo architecture. The documentation content remains at the root level (/content/docs/) for sharing, while the Next.js application is cleanly isolated in apps/docs/.
Changes:
- Replaced custom documentation CLI with Fumadocs + Next.js 16
- Restructured to monorepo with
apps/docs/containing the site and/content/docs/containing shared MDX content - Updated build scripts to categorize auto-generated schema documentation by protocol (data, ui, system, ai)
- Removed duplicate H1 headings from MDX files (now handled by page layout)
- Added proper workspace configuration with isolated dependencies
Reviewed changes
Copilot reviewed 157 out of 160 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
pnpm-workspace.yaml |
Added apps/* to workspace packages |
package.json |
Updated scripts to use workspace filters, moved dependencies to appropriate locations |
tsconfig.json |
Excluded apps and packages directories from root TypeScript config |
apps/docs/**/* |
New Next.js 16 documentation site with Fumadocs integration |
packages/spec/scripts/build-docs.ts |
Enhanced to categorize generated docs by protocol type |
content/docs/**/*.mdx |
Removed duplicate H1 titles, escaped inline code with braces |
content/docs/references/*/meta.json |
Added category metadata for navigation |
.gitignore |
Added Next.js and Fumadocs specific ignores |
pnpm-lock.yaml |
Removed @objectdocs/cli, added Fumadocs dependencies |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
| </div> | ||
|
|
||
| <h1 className="text-4xl font-extrabold tracking-tight sm:text-6xl md:text-7xl bg-gradient-to-br from-foreground to-foreground/60 bg-clip-text text-transparent pb-2"> | ||
| The Post-SaaS <br/> Operatings System |
There was a problem hiding this comment.
Spelling error: "Operatings" should be "Operating". This is a critical typo in the main heading of the homepage.
| The Post-SaaS <br/> Operatings System | |
| The Post-SaaS <br/> Operating System |
| // 1. Scan source files to build map | ||
| Object.keys(CATEGORIES).forEach(category => { | ||
| const dir = path.join(SRC_DIR, category); | ||
| if (fs.existsSync(dir)) { | ||
| const files = fs.readdirSync(dir).filter(f => f.endsWith('.ts')); | ||
| for (const file of files) { | ||
| const content = fs.readFileSync(path.join(dir, file), 'utf-8'); | ||
|
|
||
| // Regex to find exported const schemas (e.g. "export const ObjectSchema = ...") | ||
| // also matches "export const ObjectCapabilities = ..." | ||
| // We assume conventions are followed | ||
| const matches = content.matchAll(/export const (\w+)(?:Schema)?\s*=\s*z\./g); | ||
| for (const match of matches) { | ||
| // match[1] is the name (e.g. Object). | ||
| // Note: build-schemas.ts strips 'Schema' suffix. | ||
| // We match (\w+) which captures 'ObjectSchema' or 'ObjectCapabilities'. | ||
| // logic in build-schemas: `key.endsWith('Schema') ? key.replace('Schema', '') : key` | ||
|
|
||
| let schemaName = match[1]; // e.g. Object from ObjectSchema | ||
| if (!content.includes(`export const ${schemaName}Schema =`)) { | ||
| // Wait, regex above captures "Object" from "ObjectSchema" IF I put Schema in non-capturing group? | ||
| // No, (\w+) captures "ObjectSchema". (?:Schema)? is applied to verify/consume suffix but regex is tricky. | ||
| // Simplified regex: /export const (\w+)\s*=/ | ||
| // Then apply naming logic. | ||
| } | ||
| } | ||
| } | ||
| } | ||
| }); |
There was a problem hiding this comment.
Dead code: Lines 20-48 contain commented-out or incomplete code that was replaced by the scanCategories function starting at line 50. This dead code should be removed to improve maintainability and avoid confusion.
|
|
||
| export const docs = defineDocs({ | ||
| dir: '../../content/docs', | ||
| }) as any; |
There was a problem hiding this comment.
Type safety issue: The use of as any on line 5 bypasses TypeScript's type checking. The PR description mentions this is a "workaround for pnpm zod@4 type portability", but this defeats the purpose of TypeScript and could hide type errors. Consider finding a proper solution or at least adding a detailed comment explaining why this workaround is necessary and tracking it for future removal.
| }) as any; | |
| }); |
|
|
||
| export const source = loader({ | ||
| baseUrl: '/docs', | ||
| source: (docs as any).toFumadocsSource(), |
There was a problem hiding this comment.
Type safety issue: Another use of as any that bypasses TypeScript type checking. This is consistent with the workaround in source.config.ts but should be properly addressed or documented.
| source: (docs as any).toFumadocsSource(), | |
| // @ts-expect-error: fumadocs-mdx virtual module typings do not currently expose `toFumadocsSource` | |
| source: docs.toFumadocsSource(), |
| if (!fs.existsSync(DOCS_DIR)) { | ||
| fs.mkdirSync(DOCS_DIR, { recursive: true }); | ||
| // 2. Prepare Directories | ||
| const miscDir = path.join(DOCS_ROOT, 'misc'); |
There was a problem hiding this comment.
Unused variable miscDir.


Replace the custom
@objectdocs/clidocumentation tooling with Fumadocs, a modern Next.js-based documentation framework, and restructure it into a proper monorepo architecture underapps/docs/while keeping documentation content at the root level for sharing.Changes
Monorepo Structure
apps/docs/to avoid polluting the root directorypackage.jsonwith isolated dependenciespackages/*) and applications (apps/*)/content/docs/(root level) for easy access and sharing across the repositoryCore Infrastructure
/content/docs/(root level) with type-safe collection handling@tailwindcss/postcssDirectory Structure
Configuration
UI Components
fumadocs-ui/mdxBuild Output
Workspace Configuration
pnpm-workspace.yamlto includeapps/*package.jsonscripts use workspace filters:pnpm --filter @objectstack/docspackage.jsonincludes shared dependencies (lucide-react) used by MDX filestsconfig.jsonexcludes apps directory.gitignoreupdated for apps structureScreenshot
Scripts
Scripts remain the same from repository root:
Benefits
/content/docs/accessible to other tools and workflowsapps/playground,apps/studio)All existing MDX content preserved at the root level. The
.source/directory (auto-generated by Fumadocs) is gitignored.Original prompt
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.