How Fumadocs is wired
Routes, source loader, search, and LLM endpoints in this template
Fumadocs is three layers: Core (source, search, page tree), UI (docs layout and MDX components), and MDX (the content compiler). VibeKit uses all three inside apps/web. See the Fumadocs introduction for the framework view.
Packages
apps/web/package.json pins:
fumadocs-coreandfumadocs-ui(runtime)fumadocs-mdx(compiler, viacreateMDX()inapps/web/next.config.mjs)
The Next config wraps the app cleanly as withNextIntl(withMdx(nextConfig)). Fumadocs MDX compiles content/docs (documentation), content/blog (blog articles), and content/legal (terms and privacy policy), unifying all Markdown under one engine.
Source loader
apps/web/modules/docs/source.ts exposes loaders for all content:
defineDocs({ dir: "content/docs" })reads product documentation.defineDocs({ dir: "content/blog" })reads blog posts with frontmatter validation.defineDocs({ dir: "content/legal" })reads terms and legal policies.defineI18nusesconfig.i18nlocales, hides the default locale in URLs, and parses locale files with a dot suffix (page.de.md).docsSource,blogSource, andlegalSourceexposegetPage,getPageTree, andgenerateParams.
The public route is a catch-all in its own route group (not under marketing chrome): apps/web/app/(docs)/docs/[[...path]]/.
- layout.tsx renders
DocsLayoutwithdocsSource.getPageTree(locale)and the product logo. - page.tsx calls
docsSource.getPage(path, locale), thenpage.data.load()for the MDX body and table of contents.
Locale is not in the URL. getLocale() reads the NEXT_LOCALE cookie. That matches the rest of the app (localePrefix: "never").
MDX components
apps/web/modules/docs/mdx-components.tsx spreads fumadocs-ui/mdx defaults (headings, code blocks, Callout, tabs, and the rest). Add product-specific components there. See Fumadocs UI components.
The docs catch-all layout wraps documentation in Fumadocs RootProvider for search. Its theme handling is disabled because the app already owns the theme provider.
Search
GET /api/search uses createFromSource(docsSource). Each index record includes locale, title, subtitle, URL, and structured data from the compiled page. Details: Fumadocs search.
LLM endpoints
VibeKit follows the Fumadocs LLM integration:
| URL | What it returns |
|---|---|
/llms.txt | Index of docs pages |
/llms-full.txt | Full Markdown of every page |
/docs.md or /docs/getting-started/quickstart.md | One page as Markdown (rewritten to /llms.mdx/docs/...) |
Rewrites live in apps/web/next.config.mjs. Helpers live in apps/web/modules/docs/get-llm-text.ts.
Static params
generateStaticParams on the docs page uses docsSource.generateParams("path") to enumerate known slugs. Rendering still reads the locale cookie and resolved module state per request; this does not make every docs route static. Missing slugs call notFound().