Written by

Fuma Nama

At

Thu Nov 06 2025

Fumadocs OpenAPI v10

推出 Fumadocs OpenAPI v10。

Back

我们很高兴地宣布 Fumadocs OpenAPI v10 的发布。此次重要版本主要着重于增强自定义功能和简化 API 接口,同时也是淘汰旧版或已弃用 API 的机会。

🌐 We are pleased to announce the release of Fumadocs OpenAPI v10. This major release focuses on enhancing customization capabilities and simplifying API surfaces, it is also an opportunity to drop older/deprecated APIs.

我们引入了多个在升级过程中需要注意的重大变更。

🌐 We have introduced multiple breaking changes that require attention during upgrades.

重大更改

🌐 Breaking Changes

createOpenAPI 使用的重新设计

🌐 Redesign of createOpenAPI Usage

此重新设计将 API 页面和服务器职责分开,移除了 disablePlayground 选项并改用 playground.enabled,引入了客户端配置支持,并在适配器中优先使用客户端配置。

🌐 This redesign separates API page and server concerns, removes disablePlayground option in favor of playground.enabled, introduces client configuration support, and prefers client configs for adapters.

  1. API 页面和服务器的隔离:

    以前,所有选项都位于 createOpenAPI()

    lib/openapi.ts
    import { createOpenAPI } from 'fumadocs-openapi/server';
    import path from 'node:path';
    
    export const openapi = createOpenAPI({
      input: [path.resolve('./scalar.yaml')],
      proxyUrl: '/api/proxy',
      mediaAdapters: {
        /* adapters */
      },
      shikiOptions: {
        /* options */
      },
    });

    现在,你需要将 API 页面组件和服务器声明分开。

    import { createOpenAPI } from 'fumadocs-openapi/server';
    import path from 'node:path';
    
    export const openapi = createOpenAPI({
      input: [path.resolve('./scalar.yaml')],
      proxyUrl: '/api/proxy',
    });
  2. 游乐场的更多选项: 使用 playground.enabled 替代 disablePlayground

    components/api-page.tsx
    export const APIPage = createAPIPage(openapi, {
      playground: {
        enabled: false,
      },
    });
  3. 客户端配置支持:

    选项现在已分为服务器/客户端配置,某些选项已移至客户端配置,

    import client from './api-page.client';
    
    export const APIPage = createAPIPage(openapi, {
      client,
    });
  4. 客户端媒体适配器: 也请通过客户端配置转发你的媒体适配器。

    components/api-page.client.tsx
    'use client';
    import { defineClientConfig } from 'fumadocs-openapi/ui/client';
    import { adapters } from './my-media-adapters';
    
    export default defineClientConfig({
      mediaAdapters: adapters,
    });

重命名选项

🌐 Renaming Options

选项 content.showExampleInFields 已被重命名为 schemaUI.showExample

🌐 The option content.showExampleInFields has been renamed to schemaUI.showExample.

移除集中式 rendererfields API

🌐 Removal of Centralized renderer and fields APIs

Fumadocs OpenAPI 现在更倾向于按功能进行自定义,取消了集中式的 renderer API。自定义渲染函数现在可以在创建 API 页面时直接在 content 选项中指定。

🌐 Fumadocs OpenAPI now prefers per-feature customizations, eliminating the centralized renderer API. Custom render functions are now specified directly in the content option when creating an API page.

components/api-page.tsx
import { openapi } from '@/lib/openapi';
import { createAPIPage } from 'fumadocs-openapi/ui';

export const APIPage = createAPIPage(openapi, {
  content: {
    renderResponseTabs,
    renderAPIExampleLayout,
    renderAPIExampleUsageTabs,
  },
});

要迁移 Playground fields 选项,请使用客户端渲染 APIs:

🌐 For migrating Playground fields options, utilize client-side render APIs:

components/api-page.client.tsx
'use client';
import { defineClientConfig } from 'fumadocs-openapi/ui/client';

export default defineClientConfig({
  playground: {
    renderParameterField: (fieldName, field) => {
      /* custom implementation */
    },
  },
});

还提供额外的布局自定义功能:

🌐 Additional layout customizations are available:

components/api-page.tsx
import { openapi } from '@/lib/openapi';
import { createAPIPage } from 'fumadocs-openapi/ui';

export const APIPage = createAPIPage(openapi, {
  content: {
    renderResponseTabs: (tabs) => <div></div>,
    renderAPIExampleLayout: ({ selector, usageTabs, responseTabs }) => (
      <div></div>
    ),
    renderAPIExampleUsageTabs: (generators) => <div></div>,
    renderPageLayout: ({ operations, webhooks }) => <div></div>,
    renderOperationLayout: (slots) => <div></div>,
    renderWebhookLayout: ({ header, authSchemes, parameters, body, responses, callbacks }) => (
      <div></div>
    ),
  },
});

generateFiles() 需要 OpenAPI 服务器

🌐 generateFiles() Requires OpenAPI Server

文件生成现在由 OpenAPI 服务器处理。generateFilesinput 字段必须引用服务器实例,而不是文件路径的字符串数组。

🌐 File generation is now handled within the OpenAPI server. The input field for generateFiles must reference the server instance rather than a string array of file paths.

import { openapi } from '@/lib/openapi';
void generateFiles({
  input: ['./products.yaml'],
  output: './content/docs',
});

新功能

🌐 New Features

存储键前缀

🌐 Storage Key Prefix

v10 引入了 storageKeyPrefix 选项,通过隔离 localStorage 密钥来防止多个 OpenAPI 实例之间的状态混淆。

🌐 v10 introduced the storageKeyPrefix option to prevent state bleed across multiple OpenAPI instances by isolating localStorage keys.

components/api-page.client.tsx
'use client';
import { defineClientConfig } from 'fumadocs-openapi/ui/client';

export default defineClientConfig({
  storageKeyPrefix: 'fumadocs-openapi-custom-',
});

错误修复

🌐 Bug Fixes

  • TypeScript 模式输出修复: 已解决 TypeScript 模式生成错误。在此过程中禁用代码格式化以提高性能。

我们建议你根据这些更改审查你的实现,以利用改进的灵活性和性能。如果你遇到问题,欢迎向我们的 GitHub 仓库提供反馈。

🌐 We recommend reviewing your implementation against these changes to leverage the improved flexibility and performance. If you encounter issues, welcome to contribute feedback to our GitHub repository.