The loader API provides file transformation for MDX and metadata files across different bundler environments.
createMdxLoader
Creates a loader for transforming MDX files into executable JavaScript.
import { createMdxLoader } from 'fumadocs-mdx/loaders/mdx';
import type { ConfigLoader } from 'fumadocs-mdx/loaders/config';
const mdxLoader = createMdxLoader(configLoader);
Configuration loader instance that provides access to the core system
Returns
Matches .md and .mdx files with optional query strings
load
(input: LoaderInput) => Promise<LoaderOutput>
Transforms MDX content into JavaScript modules
Query Parameters
The loader accepts query parameters to customize behavior:
Name of the collection to use for this file
Workspace name for multi-workspace configurations
only
'frontmatter' | 'all'
default:"'all'"
Load only frontmatter or the complete compiled MDX
Example
import page from './content/docs/introduction.mdx?collection=docs';
// Returns compiled MDX component
import { frontmatter } from './content/docs/introduction.mdx?collection=docs&only=frontmatter';
// Returns only frontmatter data
Creates a loader for JSON and YAML metadata files.
import { createMetaLoader } from 'fumadocs-mdx/loaders/meta';
const metaLoader = createMetaLoader(configLoader, {
json: 'js',
yaml: 'js'
});
Configuration loader instance
resolve.json
'json' | 'js'
default:"'js'"
Output format for JSON files. Use 'json' for JSON modules or 'js' for ES modules
Output format for YAML files (always ES modules)
Returns
A Loader that parses and validates metadata files.
Loader Interface
The universal loader interface for different bundler environments.
interface Loader {
test?: RegExp;
load: (input: LoaderInput) => Awaitable<LoaderOutput | null>;
bun?: {
load?: (source: string, input: LoaderInput) => Awaitable<Bun.OnLoadResult>;
};
}
Regular expression to filter file paths and URLs
load
(input: LoaderInput) => Promise<LoaderOutput | null>
Transform function. Returns null to skip transformation
bun.load
(source: string, input: LoaderInput) => Promise<Bun.OnLoadResult>
Bun-specific loader for synchronous dynamic imports
interface LoaderInput {
development: boolean;
compiler: CompilerOptions;
filePath: string;
query: Record<string, string | string[] | undefined>;
getSource: () => string | Promise<string>;
}
Whether running in development mode
Compiler context for tracking dependencies
Absolute path to the file being loaded
query
Record<string, string | string[]>
Parsed query parameters from the import URL
getSource
() => string | Promise<string>
Function to retrieve the file contents
LoaderOutput
interface LoaderOutput {
code: string;
map?: unknown;
moduleType?: 'js' | 'json';
}
The transformed JavaScript or JSON code
Source map for the transformation
Module type hint (supported in Vite 8+)
Adapter Functions
Convert loaders to bundler-specific formats.
toNode
Convert to Node.js module.register() loader.
import { toNode } from 'fumadocs-mdx/loaders/adapter';
import type { LoadHook } from 'node:module';
const nodeLoader: LoadHook = toNode(mdxLoader);
toVite
Convert to Vite plugin transform hook.
import { toVite } from 'fumadocs-mdx/loaders/adapter';
const viteLoader = toVite(mdxLoader);
export default {
plugins: [
{
name: 'fumadocs-mdx',
transform: viteLoader.transform,
}
]
};
toWebpack
Convert to Webpack loader.
import { toWebpack } from 'fumadocs-mdx/loaders/adapter';
const webpackLoader = toWebpack(mdxLoader);
module.exports = {
module: {
rules: [
{
test: /\.mdx?$/,
use: [webpackLoader]
}
]
}
};
toBun
Convert to Bun plugin.
import { toBun } from 'fumadocs-mdx/loaders/adapter';
import type { BunPlugin } from 'bun';
const bunPlugin: BunPlugin = {
name: 'fumadocs-mdx',
setup(build) {
toBun(mdxLoader)(build);
}
};
ConfigLoader
Provides access to the configuration system.
interface ConfigLoader {
getCore(): Promise<Core>;
}
createStandaloneConfigLoader
Creates a config loader that manages its own lifecycle.
import { createStandaloneConfigLoader } from 'fumadocs-mdx/loaders/config';
const configLoader = createStandaloneConfigLoader({
core,
buildConfig: true,
mode: 'production'
});
Uninitialized core instance
Whether to build the configuration from source
mode
'dev' | 'production'
required
Development mode enables config hot-reloading
createIntegratedConfigLoader
Creates a config loader from an already initialized core.
import { createIntegratedConfigLoader } from 'fumadocs-mdx/loaders/config';
const configLoader = createIntegratedConfigLoader(core);
Initialized core instance
Bundler Integrations
Next.js
import { createMDX } from 'fumadocs-mdx/next';
const withMDX = createMDX({
configPath: 'source.config.ts',
outDir: '.source',
index: { target: 'default' }
});
export default withMDX({
// Next.js config
});
configPath
string
default:"'source.config.ts'"
Path to configuration file
outDir
string
default:"'.source'"
Output directory for generated files
index
IndexFilePluginOptions | false
default:"{}"
Index file generation options, or false to disable
Bun
import { createMdxPlugin } from 'fumadocs-mdx/bun';
Bun.plugin(createMdxPlugin({
environment: 'bun',
configPath: 'source.config.ts',
disableMetaFile: false
}));
configPath
string
default:"'source.config.ts'"
Path to configuration file
Skip transformation of JSON/YAML metadata files
Node.js
import { register } from 'node:module';
register('fumadocs-mdx/node/loader', import.meta.url);
The Node.js loader automatically handles .mdx and metadata files using module.register().
Build Cache
Enable experimental build caching for production builds:
export default defineConfig({
experimentalBuildCache: '.cache'
});
The cache stores compiled MDX output keyed by content hash. Delete the cache directory to invalidate.