AsyncAPI
Generating docs for AsyncAPI schema.
Setup
Install the required packages.
npm i @fumadocs/asyncapi shikiGenerate Styles
Add the following line:
@import 'tailwindcss';
@import 'fumadocs-ui/css/neutral.css';
@import 'fumadocs-ui/css/preset.css';
@import '@fumadocs/asyncapi/css/preset.css';Configure Plugin
Create the AsyncAPI server instance and the <AsyncAPIPage /> component.
import { createAsyncAPI } from '@fumadocs/asyncapi/server';
// note: this is a server-side API
export const asyncapi = createAsyncAPI({
// the AsyncAPI schema, you can also give it an external URL.
input: ['./asyncapi.yaml'],
});See createAsyncAPI() and createAsyncAPIPage() for their options.
Generate Pages
Pass staticSource() to your loader(). It generates pages without writing files.
staticSource() reads files, so source.ts becomes server-only. Move docs into collections.ts for client code to import.
import { loader } from 'fumadocs-core/source';
import { defineDocs } from 'fumadocs-mdx/macro';
import { docs } from '@/lib/collections';
import { asyncapi } from '@/lib/asyncapi';
export const docs = defineDocs({
dir: 'content/docs',
docs: {
async: true,
},
});
// server-only now, as `staticSource()` reads files
export const source = loader(
{
docs: docs.toFumadocsSource(),
asyncapi: await asyncapi.staticSource({
baseDir: 'asyncapi',
}),
},
{
baseUrl: '/docs',
// optional: adds the direction of messages to each page item in page tree
plugins: [asyncapi.loaderPlugin()],
},
);staticSource() generates a page per operation by default. See Generating Pages to customize them.
Pages of source now have two types, docs and asyncapi. 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: async (page) => {
if (page.type === 'asyncapi') {
return `# ${page.data.title}\n\n${await page.data.getText('processed')}`;
}
// your original flow below...
},
});Render AsyncAPI pages with <AsyncAPIPage /> in your docs page:
import { docs, source } from '@/lib/source';
import { docs } from '@/lib/collections';
import { source } from '@/lib/source';
import { AsyncAPIPage } from '@/components/api-page';
import type { AsyncAPI } from '@fumadocs/asyncapi';
// the type-level check of server function results can't verify AsyncAPI documents,
// register them as serializable (install `@tanstack/router-core` if it isn't resolvable)
declare module '@tanstack/router-core' {
interface SerializableExtensions {
asyncapiDocument: AsyncAPI.AsyncAPIObject;
}
}
export const Route = createFileRoute('/docs/$')({
component: Page,
loader: async ({ params }) => {
const slugs = params._splat?.split('/') ?? [];
const data = await serverLoader({ data: slugs });
if (data.type === 'docs') await docs.getPage(data.path)?.preload();
return data;
},
});
const serverLoader = createServerFn({
method: 'GET',
})
.validator((slugs: string[]) => slugs)
.handler(async ({ data: slugs }) => {
const page = source.getPage(slugs);
if (!page) throw notFound();
const pageTree = await source.serializePageTree(source.getPageTree());
if (page.type === 'asyncapi') {
return {
type: 'asyncapi',
title: page.data.title,
props: page.data.getAsyncAPIPageProps(),
pageTree,
};
}
return { type: 'docs', path: page.path, pageTree };
});
function Page() {
const data = useFumadocsLoader(Route.useLoaderData());
return (
<DocsLayout {...baseOptions()} tree={data.pageTree}>
{data.type === 'asyncapi' && (
<DocsPage full>
<DocsTitle>{data.title}</DocsTitle>
<DocsBody>
<AsyncAPIPage {...data.props} />
</DocsBody>
</DocsPage>
)}
<Suspense>
{data.type === 'docs' && <Content path={data.path} />}
</Suspense>
</DocsLayout>
);
}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 AsyncAPI integration supports AsyncAPI 3:
- The direction of messages for readers, the server and channel address of operations
- Messages with their payload and header schemas, including Avro, Protobuf and RAML schemas
- Message examples, from the document or generated from schemas
- Request and reply, correlation IDs
- Security schemes, including OAuth 2.0 flows and SASL mechanisms
- Protocol details from bindings, for the selected server
- A playground for WebSocket, Server-Sent Events and custom transports, with text and binary messages
- Code samples in JavaScript and Python, for WebSocket, MQTT, Kafka, AMQP and NATS
- TypeScript definitions of payloads and headers
- Markdown of pages for LLMs
- Traits
AsyncAPI 2 documents can be converted with npx @asyncapi/cli convert.
Demo
See the AsyncAPI example.
How is this guide?
Last updated on
