Build an Integration
An integration adds a <rapi-doc> API reference to something else: a web framework (Hono, FastAPI, Spring Boot, ASP.NET Core), a documentation site (Starlight, VitePress) or a tool (VS Code, Confluence). To put <rapi-doc> on a page of your own app, you don’t need one: see Framework Integration.
All integrations follow one contract, so they take the same options, serve the same routes and send the same HTML. This page describes it.
What an integration does
Section titled “What an integration does”- Takes the standard options (below), under the names its language prefers.
- Serves the routes: the docs page, the OAuth return page and, unless the bundle comes from a CDN,
rapidoc-min.jswith its license file. - Finds the spec: defaults
specUrlto the framework’s own OpenAPI endpoint, for example/openapi.jsonin FastAPI or/v3/api-docswith springdoc. - Ships one
rapidocrelease: the bundle, its license file andintegration.json, embedded in the integration’s package.
Options
Section titled “Options”| Option | Default | Meaning |
|---|---|---|
uiPath |
/docs |
URL path the docs page is served at, including any prefix the app is mounted under. Contract version 1 called it path, which is still read. |
specUrl |
the framework’s endpoint | URL of the OpenAPI document. |
spec |
The OpenAPI document itself, written into the page. | |
title |
API Reference |
Page title. |
assets |
bundled |
bundled: the integration serves the bundle. cdn: jsDelivr, at the pinned version with its SRI hash. Or a URL of your own. |
options |
Attributes of <rapi-doc>, in kebab-case or camelCase. |
|
head, css |
Markup and CSS added to the page as given. | |
lang, nonce |
en, none |
Page language; Content-Security-Policy nonce. |
enabled |
true |
When false, the integration registers no routes. |
In JavaScript
Section titled “In JavaScript”@rapidoc/embed implements the contract. An integration maps its routes to the framework:
import { embedRoutes, renderHostPage, renderOAuthReceiverPage } from '@rapidoc/embed';import { readAsset } from '@rapidoc/embed/node';
export function rapidoc(app, options) { for (const route of embedRoutes(options)) { app.get(route.path, (c) => { const body = route.kind === 'page' ? renderHostPage(options) : route.kind === 'oauth-receiver' ? renderOAuthReceiverPage(options) : readAsset(route.file); return c.body(body, 200, { 'content-type': route.contentType }); }); }}@rapidoc/hono is the reference integration for JavaScript server frameworks: about 80 lines over these functions, with a second entry for runtimes without a file system.
A documentation-site plugin is a different shape: the site has its own layout, bundler and sidebar, so there is no host page to serve. @rapidoc/starlight is the reference: it takes the same uiPath, spec, title and options, uses toAttributes for the element’s attributes, imports the bundle through the site’s bundler, and adds the operations to the site’s sidebar.
In runtimes without a file system, use assets: 'cdn': the page then loads the exact rapidoc version @rapidoc/embed depends on, checked against its SRI hash. A complete example on node:http is in the package (examples/node-server.js).
In other languages
Section titled “In other languages”Port the reference implementation, src/core.js of @rapidoc/embed: about 150 lines of string functions with no imports. The package has the rules in words (conformance/README.md) and fixtures (conformance/fixtures/): each has an input.json and the expected HTML or route table. Your port conforms when its output equals every fixture, byte for byte for the pages.
The Python package rapidoc is the reference for other languages (the ASP.NET Core package, RapiDocContract.cs, is a second port, in a typed language, and contract.go of rapidoc-go a third, in a repository of its own with the fixtures copied in): its contract.py is the port, and its setup_rapidoc() shows the framework side: option names in the language’s style, the framework’s own OpenAPI URL as the default, and its path-prefix setting (root_path) in the page’s URLs.
Files rapidoc publishes for integrations
Section titled “Files rapidoc publishes for integrations”Every rapidoc release has these in dist/, next to the bundles:
| File | Import | Use |
|---|---|---|
integration.json |
rapidoc/integration.json |
Version, CDN base URL, and each file’s role, content type, size and SRI hash. |
rapidoc-options.schema.json |
rapidoc/options.schema.json |
JSON Schema of every attribute: validate configuration, or generate typed options in your language. |
custom-elements.json |
rapidoc/custom-elements.json |
Custom Elements Manifest: attributes, events, slots and methods for editors and tooling. |
rapidoc.d.ts, flow.d.ts, react.d.ts, vue.d.ts |
rapidoc, rapidoc/flow, rapidoc/react, rapidoc/vue |
TypeScript types of the elements and their attributes. |
oauth-receiver.html |
The OAuth return page, for serving next to rapidoc-min.js. |
Checklist
Section titled “Checklist”- The docs page works at
uiPathwith and without a trailing slash, and under a path prefix or reverse proxy. rapidoc-min.js.LICENSE.txtis served or shipped wherever the bundle is.- The OAuth return page is on the same origin as the docs page.
- With a Content-Security-Policy, the page gets a
nonceand the policy allows the script’s origin. - The integration states which
rapidocversion it ships, and passes the fixtures of the contract version it implements. - Add the keyword
rapidoc-integrationand start the description with “RapiDoc for …”, so the package is listed with the others.@rapidoc/<host>on npm andrapidocon other registries are the official packages; a community package uses its own scope or name.