-
Notifications
You must be signed in to change notification settings - Fork 0
Initialize fumadocs documentation site at /apps/site #122
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR migrates the official documentation site from VitePress to Fumadocs, establishing a new Next.js 15-based documentation site at /apps/site with MDX content support.
Changes:
- Sets up a new Next.js 15 app with Fumadocs UI framework, Tailwind CSS, and TypeScript
- Creates MDX-based documentation content (Introduction, Quick Start, Installation)
- Implements a workaround for fumadocs-mdx source API compatibility issues
Reviewed changes
Copilot reviewed 20 out of 22 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| package.json | Adds workspace scripts for site development, build, and start commands |
| apps/site/package.json | Defines dependencies for Next.js 15, Fumadocs packages, and React 18 |
| apps/site/tsconfig.json | Configures TypeScript with Next.js-specific settings |
| apps/site/tailwind.config.ts | Sets up Tailwind with Fumadocs UI component scanning |
| apps/site/next.config.mjs | Configures Next.js with MDX support via fumadocs-mdx |
| apps/site/source.config.ts | Defines MDX compilation configuration for docs directory |
| apps/site/lib/source.ts | Implements workaround for fumadocs source API compatibility |
| apps/site/app/*.tsx | Creates root layout, homepage, and docs layout components |
| apps/site/app/docs/[[...slug]]/page.tsx | Implements dynamic docs page renderer with metadata generation |
| apps/site/content/docs/*.mdx | Adds documentation content pages |
| apps/site/.gitignore | Ignores Next.js, Fumadocs, and build artifacts |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
| // Map the docs from .source to the format expected by loader | ||
| // Note: docs from .source is wrapped by _runtime.doc(), not a plain array | ||
| const mappedDocs = docs | ||
| .filter((doc: any) => doc && doc.info && doc.info.path) | ||
| .map((doc: any) => { | ||
| let path = doc.info.path.replace(/\.mdx?$/, ''); | ||
| // Convert index.mdx to empty path for root /docs route | ||
| if (path === 'index') path = ''; | ||
|
|
Copilot
AI
Jan 20, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The use of any type bypasses TypeScript's type safety. Consider defining a proper interface for the doc structure or using type guards to validate the structure before filtering and mapping.
| // Map the docs from .source to the format expected by loader | |
| // Note: docs from .source is wrapped by _runtime.doc(), not a plain array | |
| const mappedDocs = docs | |
| .filter((doc: any) => doc && doc.info && doc.info.path) | |
| .map((doc: any) => { | |
| let path = doc.info.path.replace(/\.mdx?$/, ''); | |
| // Convert index.mdx to empty path for root /docs route | |
| if (path === 'index') path = ''; | |
| interface SourceDocInfo { | |
| path: string; | |
| } | |
| interface SourceDocData { | |
| // `default` holds the page body/component; other properties are spread through. | |
| default: unknown; | |
| // Allow additional properties without losing type safety on `default`. | |
| [key: string]: unknown; | |
| } | |
| interface SourceDoc { | |
| info?: SourceDocInfo; | |
| data: SourceDocData; | |
| } | |
| function isValidDoc(doc: unknown): doc is SourceDoc { | |
| if (typeof doc !== 'object' || doc === null) return false; | |
| const maybeDoc = doc as { info?: { path?: unknown }; data?: unknown }; | |
| if (!maybeDoc.info || typeof maybeDoc.info.path !== 'string') return false; | |
| if (typeof maybeDoc.data !== 'object' || maybeDoc.data === null) return false; | |
| return true; | |
| } | |
| // Map the docs from .source to the format expected by loader | |
| // Note: docs from .source is wrapped by _runtime.doc(), not a plain array | |
| const mappedDocs = docs | |
| .filter(isValidDoc) | |
| .map((doc) => { | |
| let path = doc.info!.path.replace(/\.mdx?$/, ''); | |
| // Convert index.mdx to empty path for root /docs route | |
| if (path === 'index') path = ''; |
| path, | ||
| data: { | ||
| ...doc.data, | ||
| body: doc.data.default, |
Copilot
AI
Jan 20, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The property name default is ambiguous in this context. Consider using a more descriptive name like component or content to clarify what this represents in the data structure.
| if (!page) notFound(); | ||
|
|
||
| // Type assertion needed due to custom data mapping | ||
| const MDX = (page.data as any).body; |
Copilot
AI
Jan 20, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Type assertion to any removes type safety. Define a proper interface for the page data structure to maintain type safety throughout the component.
| const MDX = (page.data as any).body; | ||
|
|
||
| return ( | ||
| <DocsPage toc={(page.data as any).toc} full={(page.data as any).full}> |
Copilot
AI
Jan 20, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Multiple type assertions to any in the same expression reduces type safety. Define an interface for the expected page data structure with properties like toc, full, title, description, and body.
| Create your first Object UI component: | ||
|
|
||
| ```tsx | ||
| import { ObjectUIRenderer } from '@object-ui/react'; |
Copilot
AI
Jan 20, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The component name ObjectUIRenderer does not align with the architectural guideline that references <SchemaRenderer> as the primary runtime component. Consider using SchemaRenderer for consistency with the documented architecture.
| pnpm install @object-ui/react @object-ui/components | ||
|
|
||
| # Start building with JSON | ||
| import { ObjectUIRenderer } from '@object-ui/react'; |
Copilot
AI
Jan 20, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The component name ObjectUIRenderer does not align with the architectural guideline that references <SchemaRenderer> as the primary runtime component. Consider using SchemaRenderer for consistency with the documented architecture.
| ### 3. Start Using | ||
|
|
||
| ```tsx | ||
| import { ObjectUIRenderer } from '@object-ui/react'; |
Copilot
AI
Jan 20, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The component name ObjectUIRenderer does not align with the architectural guideline that references <SchemaRenderer> as the primary runtime component. Consider using SchemaRenderer for consistency with the documented architecture.
📦 Bundle Size Report
Size Limits
|
|
✅ All checks passed!
|
Migrates the official documentation site from VitePress to Fumadocs, establishing the new site at
/apps/siteusing a multi-package architecture.Changes
Site Structure
/apps/sitewith TypeScript, Tailwind CSS, and Fumadocs UIcontent/docs/(Introduction, Quick Start, Installation)Configuration
next.config.mjssource.config.tsfor MDX compilationMonorepo Integration
/apps/*to pnpm-workspace.yamlsite:dev,site:build,site:start.gitignorefor Next.js and Fumadocs artifactsKnown Issue
Route generation requires API compatibility fix between fumadocs-mdx
.sourceexports (wrapped by_runtime.doc()) and the loader. Build succeeds but pages return 404. Requires investigation of fumadocs 15.x integration pattern.Screenshot
Original prompt
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.