Written by

Fuma Nama

At

Sun Nov 16 2025

Fumadocs MDX 14

性能改进与 API 重设计。

Back

我们很高兴地宣布 Fumadocs MDX 14。本次更新引入了几个主要的改进,旨在:

🌐 We are pleased to announce Fumadocs MDX 14. This update introduces several major enhancements designed to:

  • 提高灵活性,进一步采用插件化方法。
  • 提升性能和内存使用效率。
  • 改进浏览器/动态编译支持。

新型号

🌐 New Model

输出现在分为:

🌐 The output is now separated into:

  • .source/server 可用于服务器的内容数据(例如 RSC、SSR),不应在客户端代码中引用。
  • .source/browser 可用于浏览器的数据,带有内置的序列化、分块和加载层。
  • .source/dynamic 动态内容编译的接口,仅为包含 dynamic: true 的集合生成。

重大更改

🌐 Breaking Changes

入口文件

🌐 Entry Files

Fumadocs MDX 现在在 .source 文件夹中生成多个入口文件。

🌐 Fumadocs MDX now generates multiple entry files in .source folder.

要进行迁移,请在 tsconfig.json 中为新的入口文件添加或更新路径别名。

🌐 To migrate, add/update the path aliases in tsconfig.json for new entry files.

tsconfig.json
{
  "compilerOptions": {
    "paths": {
      "fumadocs-mdx:collections/*": [".source/*"]
    }
  }
}

从入口文件导入你的集合,而不是 @/.source

🌐 Import your collections from the entry files instead of @/.source:

import { docs } from '@/.source';
import { docs } from 'fumadocs-mdx:collections/server';

// access collections on server-side, e.g.
import { loader } from 'fumadocs-core/source';

export const source = loader({
  source: docs.toFumadocsSource(),
});

新的浏览器 createClientLoader() 应该可以与旧的使用方式无缝兼容。

🌐 The new browser createClientLoader() should work seamlessly with old usage.

请参见 浏览器条目 以获取更多 browserCollections 示例。

🌐 See Browser Entry for more examples of browserCollections.

Fumadocs 适配器

🌐 Fumadocs Adapter

loader() API 的适配器也已更改。

🌐 The adapter for loader() API is also changed.

对于 docs 系列,create.sourceAsync()(Vite)现在与 Next.js 保持一致:

🌐 For docs collection, create.sourceAsync() (Vite) is now consistent with Next.js:

import { docs } from 'fumadocs-mdx:collections/server';
import { loader } from 'fumadocs-core/source';

export const source = loader({
  baseUrl: '/docs',
  source: await create.sourceAsync(docs.doc, docs.meta),
  source: docs.toFumadocsSource(),
});

对于 doc 集合,createMDXSource()(Next.js)已重命名为 toFumadocsSource()

🌐 For doc collections, createMDXSource() (Next.js) is renamed to toFumadocsSource().

如果你在 doc 集合中使用 create.sourceAsync()(Vite),你也应该切换到 toFumadocsSource()

🌐 If you use create.sourceAsync() (Vite) for doc collections, you should also switch to toFumadocsSource().

import { blogPosts } from 'fumadocs-mdx:collections/server';
import { toFumadocsSource } from 'fumadocs-mdx/runtime/server';
import { loader } from 'fumadocs-core/source';

export const blog = loader({
  baseUrl: '/blog',
  // for Next.js
  source: createMDXSource(blogPosts, []),
  // for Vite
  source: await create.sourceAsync(blogPosts, []),
  source: toFumadocsSource(blogPosts, []),
});

异步与动态模式

🌐 Async & Dynamic Mode

在 Next.js 中,异步模式现在与 Vite 上的行为一致,可以生成异步导入。这使得服务器端分块成为可能,从而提高内存使用效率。

🌐 On Next.js, Async Mode now aligns with the behaviour on Vite to generate async imports. This enables server-side chunking to improve memory usage.

source.config.ts
import { defineDocs } from 'fumadocs-mdx/config';

export const docs = defineDocs({
  dir: 'content/docs',
  docs: {
    // This no longer forces dynamic compilation!
    async: true,
  },
});

相反,我们引入了一个 dynamic 选项来启用动态编译。这适用于 Vite 和 Next.js。

🌐 Instead, we introduced a dynamic option to enable dynamic compilation. This is available for both Vite and Next.js.

source.config.ts
import { defineDocs } from 'fumadocs-mdx/config';

export const docs = defineDocs({
  dir: 'content/docs',
  docs: {
    dynamic: true,
  },
});

通过启用异步或动态模式,相关集合被视为延迟加载,并提供 load() 函数来加载编译属性。

🌐 By enabling Async or Dynamic modes, the relevant collections are considered lazy-loaded, offering a load() function to load compiled properties.

postInstall() 的更新签名

🌐 Updated Signature for postInstall()

现在它接受框架插件选项,你可以自定义更多属性:

🌐 It now accepts the framework plugin options, you can customise more properties:

import { postInstall } from 'fumadocs-mdx/next';
// or
import { postInstall } from 'fumadocs-mdx/vite';

postInstall('source.config.ts');

getDefaultMDXOptions() -> applyMdxPreset()

为了支持更广泛的预设并适应动态模式,getDefaultMDXOptions() 已被重命名为 applyMdxPreset()

🌐 To support a broader range of presets and accommodate dynamic modes, getDefaultMDXOptions() has been renamed to applyMdxPreset().

source.config.ts
import { defineCollections, getDefaultMDXOptions } from 'fumadocs-mdx/config';
import { myPlugin } from './remark-plugin';

export const blog = defineCollections({
  type: 'doc',
  mdxOptions: getDefaultMDXOptions({
    remarkPlugins: [myPlugin],
    // Alternatively, use a function to customize plugin order:
    remarkPlugins: (v) => [myPlugin, ...v],
  }),
});

lastModified 插件介绍

🌐 Introduction of lastModified Plugin

lastModifiedTime 选项已被专用的 lastModified 插件取代。

这种转变促进了基于插件的架构,以实现更好的可扩展性。

🌐 This shift promotes a plugin-based architecture for better extensibility.

source.config.ts
import { defineConfig } from 'fumadocs-mdx/config';
import lastModified from 'fumadocs-mdx/plugins/last-modified';

export default defineConfig({
  plugins: [lastModified()],
});

移除多个 dir 支持

🌐 Removal of Multiple dir Support

不再支持在单个集合中指定多个目录。请改用 files 属性来筛选并包含特定文件。

🌐 Support for specifying multiple directories in a single collection has been discontinued. Instead, utilize the files property to filter and include specific files.

source.config.ts
import { defineDocs } from 'fumadocs-mdx/config';

export const docs = defineDocs({
  dir: 'content/guides',
  docs: {
    files: ['./i-love-fumadocs/**/*.{md,mdx}'],
  },
});

禁用 extractedReferences 的默认生成

🌐 Disabling Default Generation of extractedReferences

默认情况下不再启用 extractedReferences 的自动生成。要保留此功能,请通过 postprocess 选项显式激活它。

🌐 The automatic generation of extractedReferences is no longer enabled by default. To retain this functionality, explicitly activate it via the postprocess option.

source.config.ts
import { defineDocs } from 'fumadocs-mdx/config';

export const docs = defineDocs({
  dir: 'content/docs',
  docs: {
    postprocess: {
      extractLinkReferences: true,
    },
  },
});

Vite: generateIndexFile -> index

我们 Vite 插件的 generateIndexFile 选项已重命名为 index

🌐 The generateIndexFile option of our Vite plugin has been renamed to index.

vite.config.ts
import { defineConfig } from 'vite';
import mdx from 'fumadocs-mdx/vite';
import * as MdxConfig from './source.config';

export default defineConfig({
  plugins: [
    mdx(MdxConfig, {
      index: {
        // options
      },
    }),
  ],
});

补丁更新

🌐 Patch Changes

  • 解决了使用 Bun 时元文件验证的问题。
  • 引入优化以减少不必要的入口文件重新生成。

感谢你对 Fumadocs 的持续支持。如果在更新过程中遇到任何问题,欢迎通过我们的 GitHub 讨论区联系我们。

🌐 Thank you for your continued support of Fumadocs. If you encounter any issues during the update, welcome to reach out through our GitHub Discussions.