跳至內容
Fumadocs

產生頁面

從 OpenAPI schema 產生頁面。

staticSource() 與 dynamicSource() 會為您的 loader() 產生頁面,而 generateFiles() 則會將頁面以 MDX 檔案的形式寫入您的內容目錄。這幾個函式接受相同的選項。

頁面內容仍由 <OpenAPIPage /> 負責算繪,產生器只負責編排每個頁面中的端點與 webhook。

選項

per

自訂每個頁面包含的內容,預設為 operation。

Operation 指的是具有特定 HTTP 方法的 API 端點,例如 /api/weather:GET。
模式內容檔案路徑
tag具有相同標籤的 operation{tag_name}.mdx
file同一個 schema 檔案中的 operation{file_name}.mdx
operation每個 operation 各自一頁{operationId ?? endpoint_path}.mdx
custom請參閱下文不適用
import { openapi } from '@/lib/openapi';

await openapi.staticSource({
  per: 'tag',
});

設為 custom 時,您可以傳入一個函式,完全自訂產生流程:

Example
import type { OperationOutput } from 'fumadocs-openapi';
import { openapi } from '@/lib/openapi';

await openapi.staticSource({
  per: 'custom',
  toPages(builder) {
    const items = builder.extract();

    for (const op of items.operations) {
      const { pathItem, operation, displayName } = builder.fromExtractedOperation(op)!;

      const entry: OperationOutput = {
        type: 'operation',
        schemaId: builder.id,
        item: op,
        path: '...',
        info: {
          title: displayName,
          description: operation.description ?? pathItem.description,
        },
      };

      builder.create(entry);
    }
  },
});

設為 tag 時,您可以在標籤定義中加入 x-displayName,以控制各頁面的標題。

openapi.yaml
tags:
  - name: test
    description: this is a tag.
    x-displayName: My Test Name

頁面會與 groupBy 相同,依循 OpenAPI 3.2 的標籤階層產生;不含任何 operation 的標籤則不會產生頁面。

openapi.yaml
tags:
  - name: store
    kind: nav
  # 輸出:store/products.mdx
  - name: products
    parent: store

groupBy

在 operation 模式下,您可以用資料夾將輸出檔案分組。

值輸出
tag{tag}/{operationId ?? endpoint_path}.mdx
route{endpoint_path}/{method}.mdx (會忽略 name 選項)
none (預設){operationId ?? endpoint_path}.mdx
import { openapi } from '@/lib/openapi';

await openapi.staticSource({
  per: 'operation',
  groupBy: 'tag',
});

依 tag 分組時,會遵循 OpenAPI 3.2 的標籤階層:標籤會巢狀置於其 parent 標籤的資料夾內,而 kind 不是 nav 的標籤則會被忽略。

openapi.yaml
tags:
  - name: store
    summary: Store
    kind: nav
  - name: products
    parent: store

paths:
  /products:
    get:
      # 輸出:store/products/listProducts.mdx
      operationId: listProducts
      tags: [products]

未設定標籤的 operation 會歸入 unknown 資料夾。

name

用來控制所產生頁面檔案名稱的函式。

import { openapi } from '@/lib/openapi';

await openapi.staticSource({
  name(output) {
    const doc = this.document;
    if (output.type === 'operation') {
      const operation = doc.paths![output.item.path]![output.item.method]!;
      // operation 物件
      console.log(operation);

      return 'my-dir/filename';
    }

    const hook = this.dereferenceShallow(doc.webhooks![output.item.name])[output.item.method]!;
    // webhook 物件
    console.log(hook);
    return 'my-dir/filename';
  },
});

meta

自動產生 meta.json 檔案。

您隨時都可以手動定義 meta.json 檔案,以獲得最大的彈性。

import { openapi } from '@/lib/openapi';

await openapi.staticSource({
  meta: true,
});

或者自訂資料夾的呈現方式:

import { openapi } from '@/lib/openapi';

await openapi.staticSource({
  meta: {
    folderStyle: 'separator',
  },
});

MDX 檔案

若要將頁面輸出為 MDX 檔案,請建立一個指令碼:

scripts/generate-docs.ts
import { generateFiles } from 'fumadocs-openapi';
import { openapi } from '@/lib/openapi';

void generateFiles({
  input: openapi,
  output: './content/docs',
  // 建議您啟用此選項
  // 請確認端點描述不會破壞 MDX 語法。
  includeDescription: true,
});

使用指令碼產生文件:

bun ./scripts/generate-docs.ts

將 OpenAPIPage 元件加入您的 MDX 元件中。

src/components/mdx.tsx
import { OpenAPIPage } from '@/components/api-page'; 

export default getMDXComponents({
  wrapper: DocsBody,
  OpenAPIPage: (props) => <OpenAPIPage {...props} preloaded={{ docs: {} }} />,
});

MDX 元件模組由所有頁面共用,因此無法逐頁預先載入文件。請改為傳入 loadDocument 來載入文件。

將外掛加入您的 loader():

lib/source.ts
import { openapi } from '@/lib/openapi';
import { loader } from 'fumadocs-core/source';

export const source = loader({
  // 選用:為頁面樹中的每個頁面項目加上徽章
  plugins: [openapi.loaderPlugin()],
});

generateFiles() 也支援下列選項。

index

產生索引檔案,以卡片連結至各個產生的頁面。

import { generateFiles } from 'fumadocs-openapi';

void generateFiles({
  index: {
    // 用來產生 `href`
    url: {
      baseUrl: '/docs',
      contentDir: './content/docs',
    },
    items: [
      {
        // 輸出路徑
        path: 'index.mdx',
        // 選用:限制輸入檔案(與 server 中的 `input` 欄位相同)
        only: ['petstore.yaml'],
        // 選用:設定 frontmatter
        description: 'All available pages',
      },
    ],
  },
});

imports

在產生的 MDX 檔案中加入自訂匯入,方便您在產生的文件中引入元件、工具函式或其他相依套件。

import { generateFiles } from 'fumadocs-openapi';

void generateFiles({
  imports: [
    {
      names: ['API_BASE_URL'],
      from: '@/constants',
    },
  ],
});

這會在所有產生的 MDX 檔案中加入以下匯入:

import { API_BASE_URL } from '@/constants';

frontmatter

自訂 MDX 檔案的 frontmatter。

預設包含以下欄位:

屬性說明
title頁面標題
description頁面描述
full一律為 true,供 Fumadocs UI 使用
_openapi內部屬性
import { generateFiles } from 'fumadocs-openapi';

void generateFiles({
  frontmatter: (title, description) => ({
    myProperty: 'hello',
  }),
});

addGeneratedComment

在產生的檔案開頭加入註解,標示該檔案為自動產生。

import { generateFiles } from 'fumadocs-openapi';

void generateFiles({
  // 加入預設註解
  addGeneratedComment: true,

  // 或提供自訂註解
  addGeneratedComment: 'Custom auto-generated comment',

  // 或停用註解
  addGeneratedComment: false,
});

How is this guide?

最後更新於