產生頁面
從 OpenAPI schema 產生頁面。
staticSource() 與 dynamicSource() 會為您的 loader() 產生頁面,而 generateFiles() 則會將頁面以 MDX 檔案的形式寫入您的內容目錄。這幾個函式接受相同的選項。
頁面內容仍由 <OpenAPIPage /> 負責算繪,產生器只負責編排每個頁面中的端點與 webhook。
選項
per
自訂每個頁面包含的內容,預設為 operation。
/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 時,您可以傳入一個函式,完全自訂產生流程:
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,以控制各頁面的標題。
tags:
- name: test
description: this is a tag.
x-displayName: My Test Name頁面會與 groupBy 相同,依循 OpenAPI 3.2 的標籤階層產生;不含任何 operation 的標籤則不會產生頁面。
tags:
- name: store
kind: nav
# 輸出:store/products.mdx
- name: products
parent: storegroupBy
在 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 的標籤則會被忽略。
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 檔案,請建立一個指令碼:
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 元件中。
import type { MDXComponents } from 'mdx/types';
import { openapi } from '@/lib/openapi';
import { OpenAPIPage } from '@/components/api-page';
const serverLoader = createServerFn({
method: 'GET',
})
.validator((slugs: string[]) => slugs)
.handler(async ({ data: slugs }) => {
// ...
return {
path: page.path,
pageTree: await source.serializePageTree(source.getPageTree()),
...(await openapi.preloadOpenAPIPage(page)),
};
});
function Content({ path, components }: { path: string; components?: MDXComponents }) {
// ...
<MDX components={useMDXComponents(components)} />;
}
function Page() {
const { path, pageTree, preloaded } = useFumadocsLoader(Route.useLoaderData());
return (
<DocsLayout {...baseOptions()} tree={pageTree}>
<Suspense>
<Content
path={path}
components={{
OpenAPIPage: (props) => <OpenAPIPage {...props} preloaded={preloaded} />,
}}
/>
</Suspense>
</DocsLayout>
);
}將外掛加入您的 loader():
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?
最後更新於
