Fumadocs

Content Collections

Use Content Collections for Fumadocs

Content Collections is a library that transforms your content into type-safe data collections.

Setup

Install the required packages.

npm install @fumadocs/content-collections @content-collections/core @content-collections/mdx @content-collections/next

After the installation, add a path alias for the generated collections to the tsconfig.json.

{
  "compilerOptions": {
    "paths": {
      "@/*": ["./*"],
      "content-collections": ["./.content-collections/generated"]
    }
  }
}

In the Next.js configuration file, apply the plugin.

next.config.mjs
import { withContentCollections } from '@content-collections/next';
 
/** @type {import('next').NextConfig} */
const config = {
  reactStrictMode: true,
};
 
export default withContentCollections(config);

To integrate with Fumadocs, add the following to your content-collections.ts.

content-collections.ts
import { defineCollection, defineConfig } from '@content-collections/core';
import {
  createMetaSchema,
  createDocSchema,
  transformMDX,
} from '@fumadocs/content-collections/configuration';
 
const docs = defineCollection({
  name: 'docs',
  directory: 'content/docs',
  include: '**/*.mdx',
  schema: createDocSchema,
  transform: transformMDX,
});
 
const metas = defineCollection({
  name: 'meta',
  directory: 'content/docs',
  include: '**/meta.json',
  parser: 'json',
  schema: createMetaSchema,
});
 
export default defineConfig({
  collections: [docs, metas],
});

And pass it to Source API.

app/source.ts
import { allDocs, allMetas } from 'content-collections';
import { loader } from 'fumadocs-core/source';
import { createMDXSource } from '@fumadocs/content-collections';
 
export const { getPage, getPages, pageTree } = loader({
  baseUrl: '/docs',
  source: createMDXSource(allDocs, allMetas),
});

Done! You can access the pages and generated page tree from Source API.

import { getPage } from '@/app/source';
 
const page = getPage(slugs);
 
// MDX output
page?.data.body;
 
// Table of contents
page?.data.toc;
 
// Structured Data, for Search API
page?.data.structuredData;

MDX Options

You can customise MDX options in the transformMDX function.

import { defineCollection } from '@content-collections/core';
import { transformMDX } from '@fumadocs/content-collections/configuration';
 
const docs = defineCollection({
  transform: (document, context) =>
    transformMDX(document, context, {
      // options here
    }),
});

Import Components

To use components from other packages like Fumadocs UI, pass them to your <MDXContent /> component.

import defaultMdxComponents from 'fumadocs-ui/mdx';
import { Callout } from 'fumadocs-ui/components/callout';
import { MDXContent } from '@content-collections/mdx/react';
 
<MDXContent code="..." components={{ ...defaultMdxComponents, Callout }} />;

You can also import them in MDX Files, but it is not recommended.

Deep Dive: Why?

Content Collections uses mdx-bundler to bundle MDX files.

To support importing a package from node modules, Fumadocs added a default value to the cwd option of MDX Bundler. It works good, but we still do not recommend to import components in MDX files.

Reasons:

  • It requires esbuild to bundle these components, while it should be done by the Next.js bundler (for features of Server Components)
  • You can refactor the import path of components without changing your MDX files.
  • With Remote Sources, it doesn't make sense to add an import in MDX files.

Last updated on

On this page

Edit on Github