Fumadocs

OpenAPI

Generating docs for OpenAPI schema.

Setup

Install the required packages.

npm i fumadocs-openapi shiki

Generate Styles

Add the following line:

Tailwind CSS
@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 & <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() & createOpenAPIPage() for available options.

Generate Pages

Integrate into Loader API to generate pages, without generating real files.

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

const docs = defineDocs({
  dir: 'content/docs',
});

export const source = loader(
  {
    docs: docs.toFumadocsSource(),
    openapi: await openapi.staticSource({
      baseDir: 'openapi',
    }),
  },
  {
    baseUrl: '/docs',
    // optional: adds a badge to each page item in page tree
    plugins: [openapi.loaderPlugin()],
  },
);

It generates a page per operation by default, see Generating Pages to customize them.

It will change the type of your pages, make sure to update all references to your source.

For example, where you return text for LLM:

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...
  },
});

And update your page renderer:

app/docs/[[...slug]]/page.tsx
import { OpenAPIPage } from '@/components/api-page'; 

export default async function Page(props: PageProps<'/docs/[[...slug]]'>) {
  const params = await props.params;
  const page = source.getPage(params.slug);
  if (!page) notFound();

  if (page.type === 'openapi') {
    return (
      <DocsPage full>
        <DocsTitle>{page.data.title}</DocsTitle>
        <DocsBody>
          <OpenAPIPage {...page.data.getOpenAPIPageProps()} />
        </DocsBody>
      </DocsPage>
    );
  }

  // ...
}

Ensure the migration is complete!

Run a type check to verify before continuing, e.g.

npm run types:check

To 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

View demo.

How is this guide?

Last updated on