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
pnpm add @fumadocs/content-collections @content-collections/core @content-collections/mdx @content-collections/next
yarn add @fumadocs/content-collections @content-collections/core @content-collections/mdx @content-collections/next
bun add @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.
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
.
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.
import { allDocs, allMetas } from 'content-collections';
import { loader } from 'fumadocs-core/source';
import { createMDXSource } from '@fumadocs/content-collections';
export const source = loader({
baseUrl: '/docs',
source: createMDXSource(allDocs, allMetas),
});
Done! You can access the pages and generated page tree from Source API.
import { getPage } from '@/lib/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 { MDXContent } from '@content-collections/mdx/react';
import { getMDXComponents } from '@/mdx-components';
<MDXContent code="..." components={getMDXComponents()} />;
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.
How is this guide?