createAPIPage
Create a React component for rendering OpenAPI documentation pages.import { createAPIPage } from 'fumadocs-openapi/ui';
import { createOpenAPI } from 'fumadocs-openapi/server';
const server = createOpenAPI({
input: ['./openapi.yaml'],
});
export const APIPage = createAPIPage(server, {
// options
});
ApiPageProps
CreateAPIPageOptions
Type Generation
Code Samples
Rendering
Media Types
Layout Customization
Schema UI
Playground
Client Options
ApiPageProps
Props for the generated API page component.interface ApiPageProps {
document: Promise<ProcessedDocument> | string | ProcessedDocument;
showTitle?: boolean;
showDescription?: boolean;
operations?: OperationItem[];
webhooks?: WebhookItem[];
}
OperationItem
interface OperationItem {
path: string;
method: HttpMethods;
}
WebhookItem
interface WebhookItem {
name: string;
method: HttpMethods;
}
RenderContext
Context object passed to custom renderers:interface RenderContext {
slugger: Slugger;
schema: ProcessedDocument;
proxyUrl?: string;
mediaAdapters: Record<string, MediaAdapter>;
generateTypeScriptDefinitions: (schema: JSONSchema, ctx: GenerateTypeScriptDefinitionsContext) => Awaitable<string | undefined>;
renderMarkdown: (md: string) => ReactNode;
renderHeading: (depth: number, text: string, props?: HTMLAttributes<HTMLHeadingElement>) => ReactNode;
renderCodeBlock: (lang: string, code: string) => ReactNode;
// ... plus all CreateAPIPageOptions
}
Example: Basic Usage
import { createAPIPage } from 'fumadocs-openapi/ui';
import { createOpenAPI } from 'fumadocs-openapi/server';
const server = createOpenAPI({
input: ['./openapi.yaml'],
});
export const APIPage = createAPIPage(server);
// In your page component:
export default function Page() {
return (
<APIPage
document="./openapi.yaml"
operations={[
{ path: '/users', method: 'get' },
{ path: '/users/{id}', method: 'get' },
]}
/>
);
}
Example: Custom Layout
export const APIPage = createAPIPage(server, {
content: {
renderOperationLayout: async (slots, ctx, method) => (
<div className="grid grid-cols-2 gap-6">
<div>
{slots.header}
{slots.description}
{slots.authSchemes}
{slots.paremeters}
{slots.body}
{slots.responses}
</div>
<div className="sticky top-4">
{slots.apiPlayground}
{slots.apiExample}
</div>
</div>
),
},
});
Example: TypeScript Generation
import { createAPIPage } from 'fumadocs-openapi/ui';
export const APIPage = createAPIPage(server, {
async generateTypeScriptDefinitions(schema, ctx) {
if (typeof schema !== 'object') return;
const { compile } = await import('@fumari/json-schema-ts');
try {
return compile(schema, {
name: ctx.readOnly ? 'Response' : 'Request',
readOnly: ctx.readOnly,
writeOnly: ctx.writeOnly,
getSchemaId: ctx.schema.getRawRef,
});
} catch (e) {
console.warn('Failed to generate TypeScript:', e);
}
},
});
Example: Code Samples
import { createCodeUsageGeneratorRegistry } from 'fumadocs-openapi/requests/generators';
const codeUsages = createCodeUsageGeneratorRegistry();
codeUsages.add('typescript', {
lang: 'typescript',
label: 'TypeScript',
generate: (url, data, { mediaAdapters }) => {
const headers = data.header ? JSON.stringify(data.header, null, 2) : '{}';
const body = data.body ? JSON.stringify(data.body, null, 2) : 'undefined';
return `const response = await fetch('${url}', {
method: '${data.method}',
headers: ${headers},
body: ${body},
});
const data = await response.json();`;
},
});
export const APIPage = createAPIPage(server, {
codeUsages,
});