1. Quick Start
Docusaurus OpenAPI Docs is a set of Docusaurus packages that generate interactive API reference documentation from OpenAPI (Swagger) specifications. It parses your OpenAPI 2.0, 3.0, or 3.1 spec files and produces MDX pages with a built-in API explorer, code snippet generation, schema rendering, and sidebar navigation — all integrated into the Docusaurus documentation framework.
Key features:
- Generate API reference pages from OpenAPI 2.0/3.0/3.1 YAML or JSON specs
- Interactive "Try It" API explorer with live request/response testing
- Auto-generated code snippets in 18+ languages (Python, cURL, C#, Go, Node.js, Ruby, PHP, Java, PowerShell, Dart, JavaScript, C, Objective-C, OCaml, R, Swift, Kotlin, Rust)
- Schema documentation with discriminator, oneOf/anyOf/allOf support
- Versioned API documentation with version selector UI
- Auto-generated sidebar navigation grouped by tag or tag group
- Custom Mustache templates for full MDX output control
- Swagger 2.0 auto-conversion to OpenAPI 3.0
Prerequisites: Node.js >= 18, a package manager (npm, yarn, pnpm, or bun)
Quickest path — scaffold a new site:
npx create-docusaurus-openapi-docs my-api-docs
Creating new Docusaurus site with OpenAPI docs...
Installing dependencies with npm...
Success! Created my-api-docs
The scaffolded site comes with a working Petstore example. Start it immediately:
cd my-api-docs
npm start
[SUCCESS] Docusaurus website is running at: http://localhost:3000/
Tip
The scaffolder auto-detects your package manager from lockfiles and
npm_config_user_agent. You can also force one withnpx create-docusaurus-openapi-docs my-site --package-manager yarn.
What to try next: See Installation for adding to an existing Docusaurus site, or Configuration for customizing spec sources and sidebar behavior.
2. Installation
System Requirements
| Requirement | Minimum |
|---|---|
| Node.js | >= 18 |
| Docusaurus | 3.10.0+ |
| React | 16.8.4, 17, 18, or 19 |
| Package manager | npm, yarn 1.x, pnpm, or bun |
Option A: Scaffold a New Site
npx create-docusaurus-openapi-docs my-api-site
This copies a complete Docusaurus project template with docusaurus-plugin-openapi-docs and docusaurus-theme-openapi-docs pre-configured, a Petstore spec, and working sidebar/config files.
Available options:
| Option | Description |
|---|---|
--package-manager <pm> |
Force npm, yarn, pnpm, or bun |
--skip-install |
Skip dependency installation |
Important
The destination directory must either not exist or be empty (if using
.as the name). The scaffolder will error withDirectory already exists at <path>orDirectory not empty at <path>otherwise.
Option B: Add to an Existing Docusaurus Site
- Install both packages:
npm install docusaurus-plugin-openapi-docs docusaurus-theme-openapi-docs
- Install required peer dependencies:
npm install docusaurus-plugin-sass
- Add the theme to your
docusaurus.config.ts:
export default {
// ...
themes: ["docusaurus-theme-openapi-docs"],
plugins: [
[
"docusaurus-plugin-openapi-docs",
{
id: "openapi",
docsPluginId: "classic",
config: {
petstore: {
specPath: "examples/petstore.yaml",
outputDir: "docs/petstore",
},
},
},
],
],
};
- Set the doc item component in your preset's docs config:
presets: [
[
"classic",
{
docs: {
docItemComponent: "@theme/ApiItem",
},
},
],
],
- Generate the API docs:
npx docusaurus gen-api-docs all
Successfully created "docs/petstore/sidebar.ts"
Successfully created "docs/petstore/add-pet.api.mdx"
Successfully created "docs/petstore/get-pet-by-id.api.mdx"
...
Post-Install Verification
npx docusaurus start
Navigate to your API docs path (e.g., http://localhost:3000/petstore/) and confirm the API explorer renders with method badges, request/response schemas, and code snippets.
Warning
If you see
useTabs() must be used within a Tabs component, ensure you are running Docusaurus 3.10.0 or later. This was a known compatibility issue (GitHub issue #1395, now resolved).
3. Configuration
Configuration lives in your docusaurus.config.ts under the docusaurus-plugin-openapi-docs plugin entry. Each key inside config defines one API spec source.
Minimal Configuration
plugins: [
[
"docusaurus-plugin-openapi-docs",
{
id: "openapi",
docsPluginId: "classic",
config: {
myapi: {
specPath: "specs/openapi.yaml", // Local file or URL
outputDir: "docs/myapi",
},
},
},
],
],
Per-API Options
| Option | Type | Default | Description |
|---|---|---|---|
specPath |
string |
required | Path to OpenAPI spec file (YAML/JSON) or URL |
outputDir |
string |
required | Where generated MDX files are written |
proxy |
string |
— | CORS proxy URL prepended to API requests |
template |
string |
— | Custom Mustache template for API pages |
infoTemplate |
string |
— | Custom Mustache template for info pages |
tagTemplate |
string |
— | Custom Mustache template for tag pages |
schemaTemplate |
string |
— | Custom Mustache template for schema pages |
downloadUrl |
string |
— | URL or path for the "Download spec" button |
hideSendButton |
boolean |
false |
Hide the "Send API Request" button |
showExtensions |
boolean |
false |
Show vendor extensions (x-*) in docs |
showSchemas |
boolean |
false |
Generate schema-only pages |
showInfoPage |
boolean |
true |
Generate the API info page |
schemasOnly |
boolean |
false |
Only generate schema docs (skip endpoints) |
disableCompression |
boolean |
false |
Disable zlib compression of API JSON in frontmatter |
maskCredentials |
boolean |
false |
Mask auth credential inputs |
externalJsonProps |
boolean |
true |
Write large JSON props to external files for performance |
Sidebar Options
Nest these under sidebarOptions:
sidebarOptions: {
groupPathsBy: "tag", // "tag" or "tagGroup"
categoryLinkSource: "tag", // "tag", "info", or "auto"
customProps: {}, // Custom properties for sidebar items
sidebarCollapsible: true, // Enable collapsible sidebar categories
sidebarCollapsed: true, // Start sidebar categories collapsed
},
| Option | Values | Description |
|---|---|---|
groupPathsBy |
"tag", "tagGroup" |
How endpoints are grouped in the sidebar |
categoryLinkSource |
"tag", "info", "auto" |
What links to from the category header |
sidebarCollapsible |
boolean |
Whether sidebar categories can collapse |
sidebarCollapsed |
boolean |
Whether categories start collapsed |
Note
When using
groupPathsBy: "tagGroup", your OpenAPI spec must include thex-tagGroupsvendor extension to define the grouping structure.
Theme Configuration
In themeConfig, you can customize the API explorer behavior:
themeConfig: {
api: {
proxy: "https://cors.pan.dev",
authPersistence: "localStorage", // false | "sessionStorage" | "localStorage"
requestTimeout: 30000, // milliseconds
requestCredentials: "same-origin", // "omit" | "same-origin" | "include"
},
languageTabs: [
{ highlight: "python", language: "python", logoClass: "python" },
{ highlight: "bash", language: "curl", logoClass: "curl" },
// ... add or remove language tabs
],
},
Tip
Set
authPersistence: "localStorage"to keep API keys across browser sessions. Usefalsefor security-sensitive environments where credentials should never persist.
For the full configuration reference, see the Admin Guide.
4. Core Usage
Generating API Documentation
The plugin registers four Docusaurus CLI commands:
Generate docs for a single API:
npx docusaurus gen-api-docs <id>
Where <id> matches a key in your plugin config. Example:
npx docusaurus gen-api-docs petstore
Successfully created "docs/petstore/sidebar.ts"
Successfully created "docs/petstore/swagger-petstore-yaml.info.mdx"
Successfully created "docs/petstore/pet.tag.mdx"
Successfully created "docs/petstore/add-pet.api.mdx"
...
Generate docs for all configured APIs:
npx docusaurus gen-api-docs all
Generate only schema docs:
npx docusaurus gen-api-docs all --schemas-only
Generate with a specific plugin instance:
npx docusaurus gen-api-docs myapi -p openapi
| Flag | Description |
|---|---|
-p, --plugin-id <plugin> |
Target a specific plugin instance (required when multiple exist) |
--all-versions |
Generate docs for all configured versions |
--schemas-only |
Only generate schema documentation pages |
Warning
The
gen-api-docscommand will not overwrite existing MDX files. To regenerate, clean first withclean-api-docs, then generate again.
Cleaning Generated Docs
Clean a single API:
npx docusaurus clean-api-docs <id>
Clean all APIs:
npx docusaurus clean-api-docs all
Clean all including versions:
npx docusaurus clean-api-docs all --all-versions
Clean only schemas:
npx docusaurus clean-api-docs all --schemas-only
This removes all generated .api.mdx, .info.mdx, .tag.mdx files, the sidebar.ts, externalized .json files, and the schemas/ directory.
Working with Versioned APIs
To maintain multiple versions of the same API:
config: {
petstore: {
specPath: "specs/petstore-v2.yaml",
outputDir: "docs/petstore",
version: "2.0.0", // Required when versions is defined
label: "v2.0.0", // Required when versions is defined
baseUrl: "/petstore/swagger-petstore-yaml", // Required when versions is defined
versions: {
"1.0.0": {
specPath: "specs/petstore-v1.yaml",
outputDir: "docs/petstore/1.0.0",
label: "v1.0.0",
baseUrl: "/petstore/1.0.0/swagger-petstore-yaml",
},
},
},
},
Generate version docs:
npx docusaurus gen-api-docs:version petstore:all
Or a specific version:
npx docusaurus gen-api-docs:version petstore:1.0.0
Clean versioned docs:
npx docusaurus clean-api-docs:version petstore:all
The version system generates a versions.json file and the sidebar utilities (versionSelector, versionCrumb) render a dropdown and breadcrumb in the sidebar:
import petstoreVersions from "./docs/petstore/versions.json";
import { versionSelector, versionCrumb } from "docusaurus-plugin-openapi-docs/lib/sidebars/utils";
const sidebars = {
"petstore-2.0.0": [
{ type: "html", defaultStyle: true, value: versionSelector(petstoreVersions) },
{ type: "html", defaultStyle: true, value: versionCrumb("v2.0.0") },
// ... sidebar items
],
};
Using the Interactive API Explorer
Each generated API page includes an interactive explorer panel:
- Method + Endpoint badge — color-coded HTTP method with the full path
- Authorization — fill in API keys, Bearer tokens, OAuth2, or OpenID Connect credentials
- Parameters — form inputs for path, query, header, and cookie parameters with type validation
- Request Body — JSON editor with schema validation, file upload for multipart, and XML support
- Send Request — execute the request against the configured server (or proxy)
- Response — view status code, headers, and response body with syntax highlighting
- Code Snippets — auto-generated examples in all configured languages
Note
For cross-origin API testing, set the
proxyoption to a CORS proxy (e.g.,"https://cors.pan.dev"). Without a proxy, browser CORS policies will block requests to external APIs.
Using Custom Mustache Templates
Override the default MDX output by providing custom Mustache templates:
config: {
myapi: {
specPath: "specs/openapi.yaml",
outputDir: "docs/myapi",
template: "templates/api.mustache",
infoTemplate: "templates/info.mustache",
tagTemplate: "templates/tag.mustache",
schemaTemplate: "templates/schema.mustache",
},
},
Available template variables include {{{id}}}, {{{title}}}, {{{frontMatter.description}}}, {{{markdown}}}, {{{json}}}, {{{api.method}}}, and {{{infoPath}}}.
Using Custom Markdown Generators
For programmatic control over the generated markdown, use markdownGenerators:
import { myCustomApiMdGenerator } from "./customMdGenerators";
config: {
myapi: {
specPath: "specs/openapi.yaml",
outputDir: "docs/myapi",
markdownGenerators: {
createApiPageMD: myCustomApiMdGenerator,
},
},
},
You can override four generators: createApiPageMD, createInfoPageMD, createTagPageMD, and createSchemaPageMD. Each receives the page metadata object and must return a markdown string.
Tip
The demo site includes a working custom markdown generator at
demo/customMdGenerators.tsthat adds a server URL table to each API page. Use it as a starting point for your own customizations.
5. Common Tasks
Regenerate API Docs After Spec Changes
- Clean the existing generated files:
npx docusaurus clean-api-docs all
- Regenerate:
npx docusaurus gen-api-docs all
- Verify locally:
npx docusaurus start
Add a New API Spec
- Place the spec file in your project (e.g.,
specs/payments.yaml) - Add a new entry to the plugin config:
config: {
// existing APIs...
payments: {
specPath: "specs/payments.yaml",
outputDir: "docs/payments",
sidebarOptions: {
groupPathsBy: "tag",
categoryLinkSource: "tag",
},
},
},
- Generate docs:
npx docusaurus gen-api-docs payments
- Import the generated sidebar in your
sidebars.ts:
import paymentsSidebar from "./docs/payments/sidebar";
Use a Remote OpenAPI Spec URL
config: {
myapi: {
specPath: "https://api.example.com/openapi.json",
outputDir: "docs/myapi",
},
},
The plugin fetches and resolves the spec at generation time, including remote $ref pointers.
Enable Schema Documentation Pages
config: {
myapi: {
specPath: "specs/openapi.yaml",
outputDir: "docs/myapi",
showSchemas: true,
},
},
Schema pages are generated under docs/myapi/schemas/ as {schema-name}.schema.mdx.
Group Endpoints by Tag Groups
Use the x-tagGroups vendor extension in your OpenAPI spec, then configure:
sidebarOptions: {
groupPathsBy: "tagGroup",
},
Customize the Code Snippet Languages
In themeConfig.languageTabs, add or remove language entries:
languageTabs: [
{ highlight: "python", language: "python", logoClass: "python" },
{ highlight: "bash", language: "curl", logoClass: "curl" },
{ highlight: "go", language: "go", logoClass: "go" },
],
Each entry needs highlight (Prism language), language (Postman code-gen ID), and logoClass (CSS class for the language icon). Optionally add variant (e.g., "unirest" for Java).
Add Vendor Extension Documentation
- Add
x-*fields to your OpenAPI spec operations - Enable in the plugin config:
config: {
myapi: {
specPath: "specs/openapi.yaml",
outputDir: "docs/myapi",
showExtensions: true,
},
},
This generates a show_extensions: true frontmatter field that renders the x-codeSamples, x-deprecated-description, and other extensions inline.
Configure Authentication Persistence
themeConfig: {
api: {
authPersistence: "localStorage", // Persist across sessions
},
},
Options: false (in-memory only), "sessionStorage" (default, per-tab), "localStorage" (persistent).
Warning
Using
"localStorage"stores API credentials in the browser's local storage. Avoid this on public or shared machines.
6. Troubleshooting
Error: useTabs() must be used within a Tabs component
Cause: Incompatibility with Docusaurus versions below 3.10.0 (GitHub issue #1395).
Solution:
- Upgrade Docusaurus to 3.10.0 or later:
npm install @docusaurus/core@3.10.0 @docusaurus/preset-classic@3.10.0
- Rebuild:
npx docusaurus clean && npx docusaurus build
Prevention: Always match the Docusaurus version requirement (3.10.0+) before installing the OpenAPI packages.
Error: Document must be valid OpenAPI 3.0.0 definition
Cause: The spec file is not a valid OpenAPI document, or its structure cannot be parsed.
Solution:
- Validate your spec with a linter (e.g., Redocly CLI or Swagger Editor)
- Ensure the
openapifield is present and set to"3.0.x"or"3.1.x" - For Swagger 2.0 specs, the plugin auto-converts — but the input must still be a valid Swagger document
Prevention: Lint your spec before running gen-api-docs.
Error: Directory already exists at <path>
Cause: The create-docusaurus-openapi-docs scaffolder found an existing directory at the destination.
Solution: Choose a different name or use . to scaffold into the current (empty) directory.
Generated files not appearing or not updating
Cause: The gen-api-docs command does not overwrite existing files.
Solution:
npx docusaurus clean-api-docs all
npx docusaurus gen-api-docs all
Prevention: Always clean before regenerating.
Error: Operation must have summary or operationId defined
Cause: An operation in your OpenAPI spec is missing both summary and operationId.
Solution: Add at least one of summary or operationId to every operation in your spec. The plugin uses these to generate the MDX filename.
Uncaught Runtime Errors in the Browser
Cause: Various issues reported in GitHub issue #843 — typically related to malformed schemas, circular references, or spec edge cases.
Solution:
- Simplify circular
$refreferences (the plugin handles them but deep nesting can cause issues) - Clear the Docusaurus cache:
npx docusaurus clear - Regenerate:
npx docusaurus clean-api-docs all && npx docusaurus gen-api-docs all
Duplicate routes or wrong page when tag name equals operation ID
Cause: The slug generation creates collisions when a tag name and an operationId produce the same slug (GitHub issue #1110).
Solution: Ensure operation IDs are unique and do not collide with tag names. Consider prefixing operation IDs.
Build fails on Cloudflare Pages
Cause: The sass dependency requires native compilation which may not be available in all CI environments (GitHub issue #1048).
Solution: Ensure your CI environment has Node.js >= 18 with native build tools. Consider pre-building locally and deploying the static output.
Note
If MDX compilation fails with errors about Swagger-specific syntax (GitHub issue #802), ensure your spec is valid OpenAPI 3.x. The MDX compiler can choke on malformed description fields containing unescaped JSX-like syntax.
API requests fail with CORS errors
Cause: The API server doesn't include CORS headers for your documentation domain.
Solution: Configure a CORS proxy:
// Per-API proxy
config: {
myapi: {
proxy: "https://cors.pan.dev",
},
},
// Global proxy in themeConfig
themeConfig: {
api: {
proxy: "https://cors.pan.dev",
},
},
Caution
CORS proxies relay your API requests (including credentials) through a third-party server. Use only for testing and demo purposes — never route production traffic through a public CORS proxy.
7. FAQ
Q: Which OpenAPI specification versions are supported?
OpenAPI 2.0 (Swagger), 3.0.x, and 3.1.x. Swagger 2.0 specs are automatically converted to OpenAPI 3.0 during processing using the swagger2openapi library.
Q: Can I use a remote URL for my OpenAPI spec?
Yes. Set specPath to a full URL (e.g., "https://api.example.com/openapi.json"). The plugin detects URLs by checking for https:// or http:// prefixes and fetches them at generation time.
Q: How do I add multiple APIs to the same site?
Add multiple keys under config in the plugin options. Each key becomes an <id> you can target with gen-api-docs <id>. Use gen-api-docs all to generate all at once.
Q: Can I use multiple plugin instances?
Yes. Add the plugin multiple times with different id values. When more than one instance exists, you must pass --plugin-id <id> (or -p <id>) to the CLI commands to specify which instance to target.
Q: What is the externalJsonProps option?
When enabled (default: true), large JSON properties in generated MDX are written to separate .json files and loaded via require(). This significantly improves MDX compilation performance for large OpenAPI specs.
Q: How do I customize the generated MDX output?
Two approaches: (1) Mustache templates via template, infoTemplate, tagTemplate, and schemaTemplate options for full structural control, or (2) markdownGenerators for programmatic markdown generation. See the Core Usage section for details.
Q: Does the API explorer actually send requests?
Yes. The "Send" button in the API explorer makes real HTTP requests to the configured server (from the spec's servers field or the proxy setting). Requests are made client-side from the user's browser.
Q: How do I add custom code samples?
Use the x-codeSamples vendor extension on your OpenAPI operations:
x-codeSamples:
- lang: Python
source: |
import requests
response = requests.get("https://api.example.com/pets")
Enable with showExtensions: true in the plugin config.
Q: Can I generate only schema documentation without endpoint pages?
Yes. Set schemasOnly: true in the API config, or pass --schemas-only to the CLI commands.
Q: What happens with circular $ref references?
The plugin resolves circular references using a custom serializer that replaces circular nodes with circular() or circular(Title) markers. The resulting docs will show the schema up to the point of circularity.
Q: How do I add i18n support?
i18n for theme components is a requested feature (GitHub issues #319, #1146) but not yet fully implemented. The theme includes translationIds.ts for future translation support.