To render API documentation in an HTML page:
Paste the following template into an HTML file.
<!DOCTYPE html> <html> <head> <title>Redoc CE</title> <!-- needed for adaptive design --> <meta charset="utf-8"/> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- Redoc CE doesn't reset the body margin --> <style> body { margin: 0; padding: 0; } </style> </head> <body> <redoc spec-url="https://redocly.github.io/redoc/cafe.yaml"></redoc> <script type="module" src="https://cdn.redoc.ly/redoc/v3.x/bundles/redoc.standalone.js"></script> </body> </html>Replace the value of
spec-urlwith either:- a path to a local description file, for example:
spec-url="openapi.yaml"orspec-url="/openapi.yaml" - a full URL, for example:
spec-url="https://redocly.github.io/redoc/cafe.yaml"
The description can be an OpenAPI, AsyncAPI, or GraphQL file. A relative path is resolved against the page URL, like any other link:
spec-url="openapi.yaml"on the page/docs/index.htmlloads/docs/openapi.yaml. A root-relative path, which starts with/, loads the same file from any page:spec-url="/openapi.yaml"loads/openapi.yaml. If the server serves the page at/docswithout a trailing slash, a relative path resolves against the site root instead, sospec-url="openapi.yaml"loads/openapi.yaml.- a path to a local description file, for example:
To test the HTML file, open it in your browser. The page works directly from disk when the script comes from the CDN and the description from a URL. A description file on your disk does not load from a file:// page, so serve the folder with a static file server, for example npx http-server or python3 -m http.server, or reference the file by URL.
When the description cannot be loaded or parsed, Redoc CE shows a Failed to load API description message in the element. The message includes the underlying error.
The same element renders AsyncAPI and GraphQL descriptions, and Redoc CE detects the specification type from the file.
<redoc spec-url="https://redocly.github.io/redoc/specs/cafe-asyncapi-amqp.yaml"></redoc>
<redoc spec-url="https://redocly.github.io/redoc/specs/cafe.graphql"></redoc>
A GraphQL schema served from an API endpoint works as well. A URL that does not load as OpenAPI or AsyncAPI is read as a GraphQL schema. The detection rules and the supported versions are listed in Supported specifications.
Redoc CE is highly configurable - see the full list of configuration options.
To configure Redoc CE in HTML, add options as attributes of the <redoc> element. Attribute names are the kebab-case form of the option names: sortRequiredPropsFirst becomes sort-required-props-first. A camelCase attribute is ignored, because HTML lowercases attribute names. For an on/off option, a bare attribute or any value except false turns the option on. The exception is disable-telemetry, which works only with the value true.
The following example lists required properties first, groups all schemas under a Schemas entry in the sidebar, and hides the download panel:
<redoc
spec-url="https://redocly.github.io/redoc/cafe.yaml"
sort-required-props-first="true"
schema-definitions-tag-name="Schemas"
hide-download-buttons="true"
></redoc>
You can add as many configuration attributes as you need.
Redoc CE uses CSS variables under the hood. To customize your API documentation's appearance, override these variables in a stylesheet on your page.
Redoc CE sets a light or dark class on the <html> element. It follows the reader's system preference at first, and the choice they make with the color mode switcher at the bottom of the sidebar afterwards. Scope every override to a color mode: :root.light for light, :root.dark for dark, and :root.light, :root.dark for values shared by both. A plain :root rule has no effect, because Redoc CE adds its own :root styles when it starts and they override yours.
The following example sets the sidebar width for both color modes, and the accent color and the sidebar background for each one:
/* Shared by both color modes */
:root.light,
:root.dark {
--sidebar-width: 280px;
}
/* Light mode */
:root.light {
--color-primary-base: #2563eb;
--sidebar-bg-color: #eef2ff;
}
/* Dark mode */
:root.dark {
--color-primary-base: #60a5fa;
--sidebar-bg-color: #1e293b;
}
To use this code, either:
- Put the CSS code inside a
<style>tag in the<head>of your page. - Create a new CSS file and link it on your page:
<link rel="stylesheet" href="redoc-theme.css">.
The common CSS variables and API docs CSS variables list the variables you can override.
As an alternative to the HTML attributes, you can also initialize Redoc CE from JavaScript. Use this method to:
- pass options that are objects or arrays
- render into your own container
- create dynamic content in a page
The standalone bundle is an ES module that exports an init function:
import { init } from 'https://cdn.redoc.ly/redoc/v3.x/bundles/redoc.standalone.js';
init(specOrSpecUrl, options, element);
Where:
specOrSpecUrl: a URL or path to the description file, a parsed description object, a JSON string, or a GraphQL schema in SDLoptions(optional): the configuration options, plus the standalone optionsrouter,basePath, anddisableTelemetryelement(optional): the DOM element Redoc CE renders into. Defaults to the first<redoc>element on the page. If you omitelementand the page has noelement, initthrows an error.HTML element <redoc> is not closed
Attributes on the target element are merged into the options and take precedence over them, so a page can combine both approaches. When you call init yourself, leave the spec-url attribute off the element. Otherwise, the element also initializes itself.
The following example is an HTML page with a <div> container and a module script that renders Redoc CE into it. It shows specification extensions, lists required properties first, and adds a download link to the panel on the overview page:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Redoc CE</title>
</head>
<body>
<h1>Redoc CE in action</h1>
<div id="redoc-container"></div>
<script type="module">
import { init } from 'https://cdn.redoc.ly/redoc/v3.x/bundles/redoc.standalone.js';
init(
'https://redocly.github.io/redoc/cafe.yaml',
{
showExtensions: true,
sortRequiredPropsFirst: true,
downloadUrls: [
{ title: 'Download OpenAPI description', url: 'https://redocly.github.io/redoc/cafe.yaml' },
],
},
document.getElementById('redoc-container'),
);
</script>
</body>
</html>
The bundle also exports hydrate, which attaches Redoc CE to markup that was rendered on a server, instead of replacing it. Hydration adds interactivity to server-rendered pages, such as the static HTML that Redocly CLI build-docs produces. It takes the same arguments as init and returns a promise. The spec must be the same pre-bundled document the server rendered from.
import { hydrate } from 'https://cdn.redoc.ly/redoc/v3.x/bundles/redoc.standalone.js';
await hydrate(spec, { router: 'history', basePath: '/docs' });
You can reference the Redoc CE script in two ways. Use a link to the files hosted on a CDN, or install Redoc CE in your node_modules folder. Self-hosting is useful when you need to host in a closed environment or have requirements around external dependencies.
The standalone bundle includes React and every other dependency, so a single file is all you need to serve.
To reference Redoc CE hosted on a CDN:
In the
<script>tag, add ansrcattribute with the URL to the Redoc CE script.<script type="module" src="https://cdn.redoc.ly/redoc/v3.x/bundles/redoc.standalone.js"></script>
The v3.x path follows the newest 3.x release. To pin an exact version, replace v3.x with the version number, in the form v3.<minor>.<patch>. The latest path follows the newest release across major versions.
The same file is available from jsDelivr, which mirrors the npm package:
<script type="module" src="https://cdn.jsdelivr.net/npm/redoc@3/bundles/redoc.standalone.js"></script>
FastAPI serves Redoc CE 2.x at /redoc with its get_redoc_html() function. The function loads the script with a classic <script> tag, and the Redoc CE 3.x bundle loads only as a module script. Passing a 3.x URL in redoc_js_url alone renders a blank page, and the browser console shows Cannot use 'import.meta' outside a module.
To serve Redoc CE 3.x, turn off the built-in page and add a route that changes the tag to <script type="module">:
from fastapi import FastAPI
from fastapi.openapi.docs import get_redoc_html
from fastapi.responses import HTMLResponse
app = FastAPI(redoc_url=None)
@app.get("/redoc", include_in_schema=False)
async def redoc():
response = get_redoc_html(
openapi_url=app.openapi_url,
title=f"{app.title} - Redoc",
redoc_js_url="https://cdn.redoc.ly/redoc/v3.x/bundles/redoc.standalone.js",
with_google_fonts=False,
)
html = response.body.decode("utf-8")
html = html.replace("<script src=", '<script type="module" src=', 1)
return HTMLResponse(html)
with_google_fonts=False skips the Google Fonts stylesheet. Redoc CE 3.x uses the system font, instead of the Montserrat and Roboto fonts that FastAPI loads for Redoc CE 2.x.
The FastAPI example is a complete app with this route. The route depends on the HTML that get_redoc_html() generates. To own the whole page instead, return the HTML template from the start of this page, with spec-url set to app.openapi_url.
- Redoc CE deployment guide - Step-by-step instructions for setting up your Redoc CE project
- Configure Redoc CE - Every option you can pass as an attribute or in the
initoptions object - Telemetry in Redoc CE - What Redoc CE collects and how to turn it off