createAsyncAPIPage()
The component for rendering AsyncAPI docs content
Overview
Fumadocs AsyncAPI uses a <AsyncAPIPage /> component to render page contents, it should be a client component.
'use client';
import { createAsyncAPIPage } from '@fumadocs/asyncapi/ui';
export const AsyncAPIPage = createAsyncAPIPage({
// config
});Custom Layout
You can customize how the sections of operations are laid out.
'use client';
import { createAsyncAPIPage } from '@fumadocs/asyncapi/ui';
export const AsyncAPIPage = createAsyncAPIPage({
content: {
renderOperationLayout(slots) {
return (
<div className="flex flex-col gap-6">
{slots.header}
{slots.connection}
{slots.description}
{slots.parameters}
{slots.messages}
</div>
);
},
},
});| Slot | Renders |
|---|---|
header | the title, on pages with several operations |
connection | which way messages go, the server and channel address, and the playground |
description | the descriptions of operation and its channel, and external documentation |
usage | code samples for the selected server, beside the operation on wide pages |
authSchemes | security schemes of the server and operation |
parameters | address parameters, and the query and headers of WebSocket connections |
messages | the messages, with their payload, headers, examples and correlation ID |
reply | the reply of a request |
bindings | protocol details of the selected server |
Direction of Messages
AsyncAPI describes an application with send and receive actions. Pages flip them for readers, who talk to the application: send is shown as Receive, and receive as Send. The sidebar shows them as an arrow into or out of a phone.
Playground
Operations can be tried in a playground: readers connect with the address parameters, query and credentials, send messages from their examples as text, hex or Base64, and see the messages they receive.
A transport connects to the servers of each protocol, WebSocket (ws and wss) is built in.
'use client';
import { createAsyncAPIPage } from '@fumadocs/asyncapi/ui';
import { sseTransport } from '@fumadocs/asyncapi/playground';
export const AsyncAPIPage = createAsyncAPIPage({
playground: {
// by the protocol of servers
transports: { http: sseTransport, https: sseTransport },
// set to `false` to disable the playground
enabled: true,
},
});Browser limits
Browsers can't send headers or cookies of other sites with WebSocket connections, only credentials
in the query are supported. Pages served over HTTPS can only connect to wss servers.
Server-Sent Events
sseTransport receives the events of http and https servers with fetch, readers can't send messages on it.
- API keys are sent in headers or the query.
- HTTP bearer and basic credentials are sent in the
Authorizationheader.
It is opt-in, since webhooks are on http servers too.
Custom Transports
A transport connects to a server and reports what happens through events. For example, MQTT over WebSocket with MQTT.js:
import mqtt from 'mqtt';
import type { PlaygroundTransport } from '@fumadocs/asyncapi/playground';
export const mqttTransport: PlaygroundTransport = {
// the security schemes it applies, they become inputs of the playground
auth: (scheme) => scheme.type === 'userPassword',
connect({ url, address, auth }, events) {
const credentials = auth[0]?.value;
// the server is the WebSocket listener of broker, like `localhost:9001`
const client = mqtt.connect(`ws://${new URL(url).host}`, {
...(typeof credentials === 'object' && credentials),
reconnectPeriod: 0,
});
client.on('connect', () =>
client.subscribe(address, (error) => (error ? events.error(error.message) : events.open())),
);
client.on('message', (_topic, payload) => events.message(payload.toString()));
client.on('error', (error) => events.error(error.message));
client.on('close', () => events.close());
return {
send: (data) =>
client.publish(address, typeof data === 'string' ? data : (new Uint8Array(data) as Buffer)),
close: () => client.end(),
};
},
};'use client';
import { createAsyncAPIPage } from '@fumadocs/asyncapi/ui';
import { mqttTransport } from '@/lib/mqtt-transport';
export const AsyncAPIPage = createAsyncAPIPage({
playground: {
transports: { mqtt: mqttTransport },
},
});See PlaygroundTransport for the details.
Code Samples
Operations show how to receive or send their messages on the selected server, in JavaScript and Python.
| Protocol | JavaScript | Python |
|---|---|---|
ws, wss | WebSocket | websockets |
mqtt, mqtts, secure-mqtt | mqtt | paho-mqtt |
kafka, kafka-secure | kafkajs | confluent-kafka |
amqp, amqps | amqplib | pika |
nats | @nats-io/transport-node | nats-py |
Add generators with codeUsages, or replace the default ones:
'use client';
import {
createAsyncAPIPage,
createCodeUsageGeneratorRegistry,
registerDefaultCodeUsages,
} from '@fumadocs/asyncapi/ui';
// leave out the defaults to start from scratch
const codeUsages = registerDefaultCodeUsages(createCodeUsageGeneratorRegistry());
codeUsages.add('websocat', {
label: 'websocat',
lang: 'bash',
// `url` is the URL to connect to WebSocket channels
generate({ protocol }, { url }) {
// hidden on other protocols
if (protocol !== 'ws' && protocol !== 'wss') return '';
return `websocat "${url}"`;
},
});
export const AsyncAPIPage = createAsyncAPIPage({ codeUsages });Prop
Type
Operations can have their own samples in x-codeSamples, they replace the generated ones of the same lang, and source: false removes one.
operations:
receiveLightMeasurement:
action: receive
x-codeSamples:
- lang: js
label: SDK
source: |
lights.onMeasured((event) => console.log(event));
- lang: python
source: falseSchema UI
Customize how JSON schemas are rendered, or disable schema examples.
'use client';
import { createAsyncAPIPage } from '@fumadocs/asyncapi/ui';
export const AsyncAPIPage = createAsyncAPIPage({
schemaUI: {
showExample: true,
render(options, ctx) {
// fully custom schema renderer
return ctx.SchemaUI(options);
},
},
});TypeScript Definitions
Payloads and headers have a button to copy their TypeScript definitions, generated with @fumari/json-schema-ts.
Like the schemas on pages, they leave out readOnly properties of messages readers send, and writeOnly properties of messages they receive.
'use client';
import { createAsyncAPIPage } from '@fumadocs/asyncapi/ui';
export const AsyncAPIPage = createAsyncAPIPage({
// or `(schema, ctx) => string | undefined` to generate your own
generateTypeScriptDefinitions: false,
});Internationalization
Assuming you have configured Internationalization at UI level:
import { defineI18n } from 'fumadocs-core/i18n';
import { uiTranslations } from 'fumadocs-ui/i18n';
import { asyncapiTranslations } from '@fumadocs/asyncapi/i18n';
const i18n = defineI18n({
languages: ['en', 'cn'],
defaultLanguage: 'en',
});
export const translations = i18n
.translations()
.extend(uiTranslations())
.extend(asyncapiTranslations())
.add({
cn: {
displayName: 'Chinese',
'Messages(operation page)': '消息',
},
});See Translations for more details.
Syntax Highlighting
AsyncAPI pages highlight code blocks with Shiki, pass a highlighter to customize it.
'use client';
import { createAsyncAPIPage } from '@fumadocs/asyncapi/ui';
import { highlighter } from '@/lib/highlighter';
export const AsyncAPIPage = createAsyncAPIPage({ highlighter });Custom Components
Override the default heading and code block components.
'use client';
import { createAsyncAPIPage } from '@fumadocs/asyncapi/ui';
export const AsyncAPIPage = createAsyncAPIPage({
components: {
Heading({ id, depth, ...props }) {
const Tag = `h${depth}` as const;
return <Tag id={id} {...props} />;
},
CodeBlock({ lang, code }) {
return <pre data-lang={lang}>{code}</pre>;
},
},
});Customise UI
For customisations beyond the available options, you can install the UI into your codebase with Fumadocs CLI.
Full UI
The entire UI of API pages, built on the headless layer.
npx @fumadocs/cli add asyncapi/pageIt installs <AsyncAPIPage /> itself, your components/api-page.tsx is no longer needed.
import { AsyncAPIPage } from '@/components/api-page';
import { AsyncAPIPage } from '@/components/asyncapi/page'; Operation
The UI of a single operation, including its channel, messages and bindings.
npx @fumadocs/cli add asyncapi/operationPlayground
The playground, built on usePlayground().
npx @fumadocs/cli add asyncapi/playground'use client';
import { createAsyncAPIPage } from '@fumadocs/asyncapi/ui';
import { Operation } from '@/components/asyncapi/operation';
export const AsyncAPIPage = createAsyncAPIPage({
components: {
Operation,
},
});Schema UI
The UI of JSON schemas, shared with the other API integrations. Its state comes from <SchemaUIProvider />.
npx @fumadocs/cli add api-docs/schema'use client';
import { createAsyncAPIPage } from '@fumadocs/asyncapi/ui';
import { Schema } from '@/components/api/schema';
export const AsyncAPIPage = createAsyncAPIPage({
components: {
SchemaUI: Schema,
},
});How is this guide?
Last updated on
