Fumadocs

Getting Started

Learn how to use Fumadocs MDX in your documentation

Introduction

fumadocs-mdx is the official content source of Fumadocs. It parses frontmatter and is bundled with many MDX plugins for building a good documentation site.

This package must be used with Fumadocs

Getting Started

Install Dependencies

npm install fumadocs-mdx @types/mdx

Configuration

Add the plugin to your next.config.mjs file.

import { createMDX } from 'fumadocs-mdx/next';
 
const withMDX = createMDX();
 
/** @type {import('next').NextConfig} */
const config = {
  reactStrictMode: true,
};
 
export default withMDX(config);

It generates a .source folder once you start the dev server or start building the app. The folder contains all parsed files, you should add it to .gitignore.

ESM Only

The Next.js config must be a .mjs file since Fumadocs is ESM-only.

To configure Fumadocs MDX, create a config file.

source.config.ts
import { defineDocs } from 'fumadocs-mdx/config';
 
export const { docs, meta } = defineDocs();

Post Install

You can add a post install script to generate types before executing CLI tools (e.g. ESLint).

package.json
{
  "scripts": {
    "postinstall": "fumadocs-mdx"
  }
}

Resolve Files

To integrate with Fumadocs, create:

app/source.ts
import { docs, meta } from '@/.source';
import { createMDXSource } from 'fumadocs-mdx';
import { loader } from 'fumadocs-core/source';
 
export const source = loader({
  baseUrl: '/docs',
  source: createMDXSource(docs, meta),
});

For more customisation options, check Source API.

Start Server

next dev

A .source folder should be created. You can log and see if it is loaded correctly.

See Pages Conventions to learn how to organize your pages.

Usages

Usually, you'll interact with Fumadocs MDX through Source API (the loader). You can see the type definitions to find the available properties.

To render the page, pass components to the body.

page.tsx (Fumadocs UI)
import { source } from '@/app/source';
import type { Metadata } from 'next';
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: { slug?: string[] };
}) {
  const page = source.getPage(params.slug);
  if (!page) notFound();
 
  const MDX = page.data.body;
 
  return (
    <DocsPage toc={page.data.toc} full={page.data.full}>
      <DocsTitle>{page.data.title}</DocsTitle>
      <DocsDescription>{page.data.description}</DocsDescription>
      <DocsBody>
        <MDX components={{ ...defaultMdxComponents }} />
      </DocsBody>
    </DocsPage>
  );
}
 
export async function generateStaticParams() {
  return source.generateParams();
}
 
export function generateMetadata({ params }: { params: { slug?: string[] } }) {
  const page = source.getPage(params.slug);
 
  if (!page) notFound();
 
  return {
    title: page.data.title,
  } satisfies Metadata;
}

FAQ

Built-in Properties

These properties are exported from MDX files by default.

PropertyDescription
frontmatterFrontmatter
tocTable of Contents
structuredDataStructured Data, useful for implementing search

MDX Plugins

You can customise the options passed to the MDX processor.

source.config.ts
import { defineConfig } from 'fumadocs-mdx/config';
import rehypeKatex from 'rehype-katex';
import remarkMath from 'remark-math';
 
export default defineConfig({
  mdxOptions: {
    remarkPlugins: [remarkMath],
    // When order matters
    rehypePlugins: (v) => [rehypeKatex, ...v],
  },
});

See Configuration to learn more.

Last updated on

On this page

Edit on GitHub