OpenAPI
Generating docs for OpenAPI schema.
Setup
Install the required packages.
npm i fumadocs-openapi shikiGenerate Styles
Add the following line:
@import 'tailwindcss';
@import 'fumadocs-ui/css/neutral.css';
@import 'fumadocs-ui/css/preset.css';
@import 'fumadocs-openapi/css/preset.css';Configure Plugin
Create the OpenAPI server instance and the <OpenAPIPage /> component.
import { createOpenAPI } from 'fumadocs-openapi/server';
// note: this is a server-side API
export const openapi = createOpenAPI({
// the OpenAPI schema, you can also give it an external URL.
input: ['./openapi.json'],
});See createOpenAPI() and createOpenAPIPage() for their options.
Generate Pages
Pass staticSource() to your loader(). It generates pages without writing files.
import { getCollection } from 'astro:content';
import { loader } from 'fumadocs-core/source';
import { toFumadocsSource } from '@fumadocs/astro/source';
import { openapi } from '@/lib/openapi';
export const source = loader(
{
docs: toFumadocsSource(await getCollection('docs'), await getCollection('meta')),
openapi: await openapi.staticSource({
baseDir: 'openapi',
}),
},
{
baseUrl: '/docs',
// optional: adds a badge to each page item in page tree
plugins: [openapi.loaderPlugin()],
},
);staticSource() generates a page per operation by default. See Generating Pages to customize them.
Pages of source now have two types, docs and openapi. Update every place that uses source, like where you return text for LLMs:
import { llms } from 'fumadocs-core/source';
import { source } from '@/lib/source';
export const docsLlms = llms(source, {
renderPage: (page) => {
if (page.type === 'openapi') {
// e.g. return the stringified OpenAPI schema
return JSON.stringify(page.data.getSchema().bundled, null, 2);
}
// your original flow below...
},
});Render OpenAPI pages in an island of their own, which wraps <OpenAPIPage /> with the docs layout:
---
import type { GetStaticPaths, InferGetStaticPropsType } from 'astro';
import Layout from '@/layouts/Layout.astro';
import { Docs } from '@/components/docs';
import { OpenAPIDocs } from '@/components/openapi-docs';
import { source } from '@/lib/source';
export const prerender = true;
export const getStaticPaths = (() => {
return source.getPages().map((page) => ({
params: { slug: decodeURI(page.slugs.join('/')) || undefined },
props: { page },
}));
}) satisfies GetStaticPaths;
type Props = InferGetStaticPropsType<typeof getStaticPaths>;
const { page } = Astro.props;
const pageTree = await source.serializePageTree(source.getPageTree());
---
{/* [!code ++:13] */}
{page.type === 'openapi' && (
<Layout title={page.data.title ?? 'My App'}>
<OpenAPIDocs
client:load
pathname={Astro.url.pathname}
params={Astro.params}
tree={pageTree}
title={page.data.title}
props={page.data.getOpenAPIPageProps()}
/>
</Layout>
)}Ensure the migration is complete!
Run a type check before continuing:
npm run types:checkTo write MDX files into your content directory instead, see MDX Files.
Features
The official OpenAPI integration supports:
- Basic API endpoint information
- Interactive API playground
- Example code to send request (in different programming languages)
- Response samples and TypeScript definitions
- Request parameters and body generated from schemas
Demo
How is this guide?
Last updated on
