Fumadocs

Source API

Turn a content source into a unified interface

Usage

Source API is a helper to load file-system based content sources, it offers a unified interface to integrate content sources with Fumadocs.

It handles some important jobs:

  • Build page trees based on file system
  • Generate Urls and slugs based on file path
  • Output useful utilities to search or walk over files

It doesn't rely on the real file system (zero node:fs usage), a virtual storage is also allowed.

You can use it with built-in content sources like Fumadocs MDX.

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

The output page tree strictly follows Page Conventions.

Base URL

As the loader function also generate an URL for each page, you can override the default base URL.

import { loader } from 'fumadocs-core/source';
 
loader({
  baseUrl: '/docs',
});

Icons

Load the icon property specified by pages and meta files.

import { loader } from 'fumadocs-core/source';
import { icons } from 'lucide-react';
import { createElement } from 'react';
 
loader({
  icon(icon) {
    if (!icon) {
      // You may set a default icon
      return;
    }
 
    if (icon in icons) return createElement(icons[icon as keyof typeof icons]);
  },
});

Root Directory

Filter the input files by its located directory.

import { loader } from 'fumadocs-core/source';
 
loader({
  rootDir: 'test',
});

Content sources only provide a virtual file path to the loader (like test/index.mdx). Relative paths such as ./ and ../ are not supported.

Be Careful

This is not equivalent to your content directory configured on content source (e.g. Fumadocs MDX dir option). Please use relevant options on your source instead.

Deep Dive

As mentioned, Source API doesn't rely on real file systems. During the process, your input source files will be parsed and form a virtual storage to avoid inconsistent behaviour between different OS.

Transformer

To perform virtual file-system operations before processing, you can add a transformer.

import { loader } from 'fumadocs-core/source';
 
loader({
  transformers: [
    ({ storage }) => {
      storage.makeDir();
    },
  ],
});

Page Tree

The page tree is generated from your file system, using the Page Tree Builder. It also filters out some unnecessary information (e.g. file path), which means after the generation process, you cannot access the file path of a page node.

To customise the process, use the pageTree option. You can attach custom properties to page tree nodes, like customising the display name of pages and folders.

import { loader } from 'fumadocs-core/source';
 
loader({
  pageTree: {
    attachFile(node, file) {
      // you can access its file information
      console.log(file.data);
 
      return node;
    },
  },
});

JSX nodes are also allowed.

import { loader } from 'fumadocs-core/source';
 
loader({
  pageTree: {
    attachFile(node) {
      node.name = <>Some JSX Nodes here</>;
      return node;
    },
  },
});

Custom Source

To plug your own content source, create a Source object.

It includes a files property which is an array of virtual files. Each virtual file must contain its file path and corresponding data. You can check type definitions for more info.

Since Source API doesn't rely on file system, file paths cannot be absolute or relative (for example, ./file.mdx and D://content/file.mdx are not allowed). Instead, pass the file paths like file.mdx and content/file.mdx.

import { Source } from 'fumadocs-core/source';
 
export function createMySource(): Source<{
  metaData: { title: string; pages: string[] }; // Your custom type
  pageData: { title: string; description: string }; // Your custom type
}> {
  return {
    files: [],
  };
}

Last updated on

On this page

Edit on GitHub