Skip to content

Embed and the play panel

specbook build writes specbook.js next to your docs. Load it on any page and mark what should run:

docs.html
<p data-specbook-try="petstore/GetPetById">Fetch a pet.</p>
<button type="button" data-specbook-flow="adopt-pet" data-specbook-inputs='{"quantity":2}'>
Adopt two
</button>
<script type="module" src="/specbook/specbook.js"></script>

A plain element gets a Play button beside it. A button or link that carries the attribute opens the panel itself.

Attribute What it does
data-specbook-try="service/Operation" Opens a request. A bare Operation works when the build has one service. A request file such as requests/petstore/find-pets.req.ts opens that saved request, with its checks.
data-specbook-flow="id" Opens a flow by its id.
data-specbook-example="name" Starts from a named example.
data-specbook-inputs='{"quantity":2}' Sets a flow’s inputs, over their defaults.
data-specbook-env="demo" Chooses the environment. Set it on an element or on any ancestor, so a page can set it once.
data-specbook-tab="docs" Opens on the Docs tab instead of Try.
data-specbook-auto-run Runs as soon as the panel opens. Never against production.
data-specbook-theme="light" Pins the theme. host (the default) follows the page, and auto follows the visitor’s system.

The panel is a dialog on a desktop and a sheet from the bottom on a phone. It follows the page’s light or dark theme and keeps what a visitor types out of the page’s storage. The script also fires specbook:open and specbook:close on the trigger, and exports open and close.

The script works under script-src 'self', with no eval and no inline <style> element. The code editors set inline style attributes, so a strict policy also needs style-src-attr 'unsafe-inline'.

The viewer opens any OpenAPI address inside your page. On your own origin there is no CORS, and your visitor’s cookies are sent.

docs.html
<div id="app"></div>
<script type="application/json" id="specbook-config">{"spec": "/openapi.json"}</script>
<script type="module" src="/specbook/specbook.js"></script>

spec may be a relative address, and baseUrl sets the API address when the document has none.

Situation What to do
It is your API Embed the viewer in your docs route. It runs on your origin, so there is no CORS and cookies are sent.
Your policy blocks third-party scripts Self-host the viewer. The built folder ships in @specbook/ui as dist-viewer/.
You want the hosted viewer in your page An iframe of ui.specbook.dev works, but it is cross-origin, so the API must allow it.
It is someone else’s API It works when that API allows calls from a browser.