Fumadocs Setup Guide
Step-by-step guide to set up Fumadocs documentation from scratch.
This guide walks through setting up Fumadocs documentation from scratch, following the official documentation.
Phase 1: Install & Configure Core
Install Packages
What: Install Fumadocs core packages
Why: These provide MDX processing, page tree generation, and UI components
pnpm add fumadocs-mdx fumadocs-core fumadocs-ui @types/mdxCreate source.config.ts
What: Configure where your MDX content lives
Why: Fumadocs MDX uses this to generate the .source folder with type-safe collections
// source.config.ts (root)
import { defineDocs, defineConfig } from "fumadocs-mdx/config";
export const docs = defineDocs({
dir: "content/docs",
});
export default defineConfig();Update Next.js Config
What: Rename next.config.ts → next.config.mjs and add Fumadocs MDX plugin
Why: Fumadocs MDX is ESM-only; the plugin handles MDX compilation
// next.config.mjs
import { createMDX } from "fumadocs-mdx/next";
const config = {
reactStrictMode: true,
};
const withMDX = createMDX();
export default withMDX(config);Update tsconfig.json
What: Add path alias for Fumadocs collections
Why: Enables clean imports like fumadocs-mdx:collections/server
{
"compilerOptions": {
"paths": {
"@/*": ["./src/*"],
"fumadocs-mdx:collections/*": [".source/*"]
}
}
}Phase 2: Root Layout & Styles
Update globals.css
What: Import Fumadocs UI styles
Why: Provides the documentation theme and component styles
/* src/app/globals.css */
@import "tailwindcss";
@import "fumadocs-ui/css/neutral.css";
@import "fumadocs-ui/css/preset.css";
/* Your existing styles below */Update Root Layout
What: Wrap app in RootProvider
Why: Provides theme, search, and context for Fumadocs components
// src/app/layout.tsx
import { RootProvider } from "fumadocs-ui/provider/next";
import type { ReactNode } from "react";
import "./globals.css";
export default function RootLayout({ children }: { children: ReactNode }) {
return (
<html lang="en" suppressHydrationWarning>
<body className="flex flex-col min-h-screen">
<RootProvider>{children}</RootProvider>
</body>
</html>
);
}Create mdx-components.tsx
What: Register MDX components globally
Why: Allows MDX to use Fumadocs UI components (Cards, Callouts, Tabs, etc.)
// mdx-components.tsx (root)
import defaultMdxComponents from "fumadocs-ui/mdx";
import type { MDXComponents } from "mdx/types";
export function getMDXComponents(components?: MDXComponents): MDXComponents {
return {
...defaultMdxComponents,
...components,
};
}Phase 3: Source & Docs Layout
Create lib/source.ts
What: Export the docs source with page tree
Why: This connects your MDX content to Fumadocs routing
// src/lib/source.ts
import { docs } from "fumadocs-mdx:collections/server";
import { loader } from "fumadocs-core/source";
export const source = loader({
baseUrl: "/docs",
source: docs.toFumadocsSource(),
});Create lib/layout.shared.tsx
What: Shared layout options (nav title, links)
Why: DRY config for navbar across layouts
// src/lib/layout.shared.tsx
import type { BaseLayoutProps } from "fumadocs-ui/layouts/shared";
export function baseOptions(): BaseLayoutProps {
return {
nav: {
title: "Evolphin UI",
},
links: [{ text: "Docs", url: "/docs", active: "nested-url" }],
};
}Create Docs Layout
What: Sidebar + content layout for docs pages
Why: Provides standard documentation UX with navigation
// src/app/docs/layout.tsx
import { DocsLayout } from "fumadocs-ui/layouts/docs";
import { baseOptions } from "@/lib/layout.shared";
import { source } from "@/lib/source";
import type { ReactNode } from "react";
export default function Layout({ children }: { children: ReactNode }) {
return (
<DocsLayout {...baseOptions()} tree={source.pageTree}>
{children}
</DocsLayout>
);
}Create Docs Page
What: Dynamic route that renders MDX content
Why: Catches all /docs/* routes and renders the correct page
// src/app/docs/[[...slug]]/page.tsx
import { source } from "@/lib/source";
import {
DocsPage,
DocsBody,
DocsTitle,
DocsDescription,
} from "fumadocs-ui/page";
import { notFound } from "next/navigation";
import defaultMdxComponents from "fumadocs-ui/mdx";
export default async function Page({
params,
}: {
params: Promise<{ slug?: string[] }>;
}) {
const { slug } = await params;
const page = source.getPage(slug);
if (!page) notFound();
const MDX = page.data.body;
return (
<DocsPage toc={page.data.toc}>
<DocsTitle>{page.data.title}</DocsTitle>
<DocsDescription>{page.data.description}</DocsDescription>
<DocsBody>
<MDX components={defaultMdxComponents} />
</DocsBody>
</DocsPage>
);
}
export function generateStaticParams() {
return source.generateParams();
}Phase 4: Content Structure
Create Index Page
Create content/docs/index.mdx:
---
title: Welcome to Evolphin UI
description: A beautiful, modern component library built on shadcn/ui
---
## Getting Started
Welcome to the Evolphin UI documentation.Create Meta File
Create content/docs/meta.json:
{
"title": "Documentation",
"pages": ["index", "..."]
}The "..." means "include all other pages automatically".
Phase 5: Verify
- Stop any running dev server
- Delete
.nextfolder (clean build) - Run
pnpm dev - Visit
http://localhost:3000/docs
What You Get
| Feature | Status |
|---|---|
MDX content in content/docs/ | ✅ |
| Sidebar navigation | ✅ |
| Search (Orama, Ctrl+K) | ✅ |
| Dark/light theme toggle | ✅ |
| Table of contents | ✅ |
| Code syntax highlighting | ✅ |
| Cards, Callouts, Tabs, Steps | ✅ |