Skip to content
v12.2
GitHub

Migrating from RapiDoc v11 to v12

RapiDoc v12 cleans up the styling API. Theming uses the same CSS variable names as shadcn/ui, every variable RapiDoc reads now has a default defined on the element (no more “not defined” hooks in DevTools), and titles render as real <h1>–<h6> headings.

v12 has no compatibility aliases: rename the variables below in your CSS when you upgrade.


v11 v12
--font-regular --font-sans
--rapidoc-font, --portal-font --font-sans (set on rapi-doc)
--rapidoc-font-mono, --portal-font-mono --font-mono (set on rapi-doc)
--rapidoc-bg, --portal-bg --background (set on rapi-doc)
--rapidoc-fg, --portal-fg --foreground (set on rapi-doc)
--nav-hover-bg --sidebar-accent
--nav-hover-fg --sidebar-accent-foreground
--nav-accent-fg --sidebar-primary (also colors the active item’s left marker)
--nav-width --sidebar-width
--nav-item-padding --sidebar-item-padding
--nav-logo-max-height --sidebar-logo-max-height
--input-border --input (now the shadcn/ui meaning: border color of form fields)
--input (as a background) --input-background
--card-radius, --border-radius --radius (cards and dialogs use min(var(--radius), 0.5rem))
--code-fg, --markdown-fg, --inline-code-fg --foreground
--inline-code-bg --muted
--method-copy, --method-purge --method-default
--red for errors and required markers --destructive (--red remains for x-badges colors)

Removed because setting them had no effect: --code-property-color, --code-keyword-color, --code-operator-color, --ui-base-size, --scroll-bar-width, --layout, --primary-hover, --schema-description-threshold, --schema-field-name-threshold.

Removed undocumented layout hooks: --content-padding and --read-mode-bottom-padding (style the section-main-content part instead).

New variables:

  • --sidebar, --sidebar-foreground, --sidebar-border, --sidebar-ring: shadcn/ui sidebar tokens for the navigation bar.
  • --destructive: errors, required-field markers, and DEPRECATED labels.
  • --scroll-margin-top (default 120px): space kept above a section when navigation scrolls to it.
  • Heading scale: --h1-font-size … --h6-font-size, --heading-font, --heading-weight, --heading-line-height, --heading-color, --heading-letter-spacing, --heading-margin-top, --heading-margin-bottom, --label-heading-font-size, --line-height, --paragraph-spacing.
  • --font-size-xs (default 11px, 12px with scale="lg"): the smallest text RapiDoc renders (badges, sidebar method tags, oneOf/anyOf chips, constraint labels, tiny buttons).
  • --font-size-description (default 13px, 12px with scale="sm", 15px with scale="lg"): parameter, property, and response-header descriptions.

--ring now defaults to var(--primary) in every theme. In v11 it was missing for the default amber theme, so keyboard focus had no visible ring.


Set variables on the rapi-doc element. A rule on the element overrides RapiDoc’s built-in theme, and inherit takes the value from your page’s :root, so a shadcn/ui theme carries over without copying values:

rapi-doc {
--background: inherit;
--foreground: inherit;
--card: inherit;
--card-foreground: inherit;
--primary: inherit;
--primary-foreground: inherit;
--muted: inherit;
--muted-foreground: inherit;
--border: inherit;
--input: inherit;
--radius: inherit;
--sidebar: inherit;
--sidebar-foreground: inherit;
--sidebar-primary: inherit;
--sidebar-accent: inherit;
--sidebar-accent-foreground: inherit;
--sidebar-border: inherit;
--font-sans: inherit;
--font-mono: inherit;
}

Variables set on an ancestor (:root, body) without this rule do not reach RapiDoc, because RapiDoc defines its own defaults on the element.


RapiDoc titles are now real headings, so they share sizes and spacing with Markdown/MDX pages around them:

Level Content
h1 API title (the version is a badge, part label-overview-version)
h2 API Server, Authentication, tag groups, tags
h3 Operation summaries
h4 Request, Response, Code samples, Callbacks
h5 Parameter, request body, and response header labels

All existing CSS parts are unchanged. New parts: heading and heading-1 … heading-6 on every generated heading, plus section-auth-title, section-request-title, and section-response-title.

Section titles are now written in normal case (“API Server”, “Authentication”). The small labels (Request, Path parameters, …) still display in capitals through CSS.


  • Inline code, markdown text, and code-block text follow the theme’s --foreground and --muted instead of fixed colors.
  • View-mode operation borders use the --method-* colors (same as the method badges).
  • Headings are bolder (600) and larger, and paragraphs inside descriptions are 1em apart.
  • No text is smaller than 11px. Sidebar method tags, oneOf/anyOf chips, and small badges were 9–10px; they now use --font-size-xs, which also follows the scale attribute.
  • Parameter and property descriptions are 13px (--font-size-description) instead of 12px.
  • Sidebar navigation text uses --font-size-regular, the body text size: 14px instead of 13px (13px with scale="sm", 16px with scale="lg"), with a 20px line height instead of 16px. Rows are a few pixels taller; use nav-item-spacing="compact" for very long API lists.
  • The first label inside the Request panel (Path parameters, Request body, …) sits right under the Request heading instead of 24px below it.
  • Markdown tables in descriptions are display: block and scroll horizontally inside their own box when wider than the space available, instead of widening the page.
  • Buttons, inputs, and selects use two shared sizes that follow the scale attribute: default (~28px) for panel actions and form fields, small (~24px) for controls inside a panel. Inputs in parameter rows are taller (~35px) to line up with the two-line parameter label. Buttons are flat (no drop shadow).
  • Copy buttons are small outline buttons. Their part changed from btn btn-fill btn-copy to btn btn-outline btn-copy; target ::part(btn-copy) to style them.
  • Read mode: tag groups (x-tagGroups) are a small muted uppercase label right above their first tag instead of a large --primary heading, and tag groups, tags, and operations are separated by one thin --border rule each (no --primary rules, no divider before a tag’s first operation).
  • Allowed values and examples next to a parameter are keyboard-focusable buttons drawn as compact accent links with a dotted underline (solid on hover and focus), and plain text when Try is off. Their parts are unchanged (anchor-param-constraint, anchor-param-example).
  • Links use the theme’s accent as text, --primary-text, instead of a fixed blue. --primary-text is --primary adjusted to be readable (4.5:1) in each color scheme (--primary-text-dark, --primary-text-light). Links in descriptions carry a quiet underline that turns solid on hover; other links are underlined on hover.
  • Response status codes are a segmented control; the selected code is tinted with --primary instead of filled.
  • An operation’s authentication chips sit right under its method and path, before the description, after a lock icon. The “Authorization” label is kept for screen readers only.
  • The chips no longer link to the Authentication section; they only open their details popover. The lock icon is the link now, and the anchor-operation-security part moved from the chip labels to it.

Request parameters, request-body form fields, response headers, server variables, and the Authentication section were <table role="presentation"> layouts. They are now lists on a CSS grid:

<ul class="param-list" part="param-list" role="list">
<li class="param" part="param">
<div class="param-label" part="param-label">
<div class="param-name" part="param-name">limit</div>
<div class="param-type" part="param-type">int32</div>
</div>
<div class="param-input" part="param-input"><input part="textbox textbox-param" /></div>
<div class="param-constraint" part="param-constraint">Min 1 | Max 100</div>
<div class="param-details" part="param-details">Description and examples</div>
</li>
</ul>
  • Layout. The list is a three-column grid (var(--param-label-width) minmax(10rem, 1fr) minmax(0, 1.5fr)) and each .param is a subgrid row, so columns line up and every row’s border reaches the edge. Without constraints the input spans both right-hand columns; without an input (allow-try="false", response headers) the constraints do. Below about 36rem of container width everything stacks in one column, with no horizontal scrolling.
  • One label width. The label column was 200px in read and focused mode and 160px in view mode. It is now --param-label-width (12rem) everywhere.
  • Response headers show name and type on the left, the schema example (as “Example:”) in the constraints column, and the description below. The list is full width.
  • Constraints are a definition list, <dl class="param-constraint">, with one <dt> label and <dd> value per constraint (Default, Pattern, Limits, Allowed). The labels share one column, so every value starts at the same place, whether there is one constraint or several. Range, multiple-of, and length limits, which had no label, are now under “Limits:” and wrap like allowed values. New part: param-constraint-label. When a parameter has constraints but no description, its short-format examples become the last row of this list (“Examples:”), lined up with the other values; otherwise they stay under the description.
  • Allowed values and short-format examples are a <div class="value-list"> with a label and a <ul class="value-list-items"> of values. Wrapped lines line up under the first value, and the ┃ separators are drawn in CSS (li::after) so a line never starts with one. Long-format examples (with a summary or description) are a <ul class="param-example-list" part="param-example-list"> with no marker (the v11 disclosure triangle looked clickable); each entry has a thin left rule, which turns --primary while the entry is hovered or its example link has focus.
  • Operation security chips use the same value-list layout: .operation-security holds a .security-label-group (“Authorization” and the lock) and a <ul class="value-list-items security-chips"> with one <li> per chip. Wrapped chips line up under the first chip, and OR is drawn in CSS at the end of each line, so the .security-or element is gone.
  • Authentication is <ul class="auth-list" id="auth-list" part="auth-list"> with one <li id="security-scheme-{id}" class="auth-scheme {type}" part="auth-scheme"> per scheme; OAuth flows are in <div class="auth-flows" part="auth-flows"> inside their scheme instead of a separate row.
Removed Use instead
.m-table, .m-table.padded-12, tr / td selectors .param-list, .param, .param-*, .auth-list, .auth-scheme
#auth-table #auth-list, part auth-list
Fixed 200px / 160px label column --param-label-width

New CSS parts: param-list, param, param-label, param-name, param-type, param-input, param-constraint, param-constraint-label, param-details, value-list, value-list-label, value-list-items, auth-list, auth-scheme, and auth-flows. anchor-param-constraint is now exported from requests and responses as well.

New CSS variables: --param-label-width, --param-gap, --param-row-gap, --param-padding, --value-list-gap, --value-list-row-gap, --value-list-label-gap, and --auth-scheme-padding.

rapi-doc {
--param-label-width: 14rem;
}
rapi-doc::part(param) {
padding-block: 0.75rem;
}
rapi-doc::part(param-name) {
font-weight: 600;
}

v11 downloaded three weights of Open Sans from fonts.gstatic.com on every page unless you set load-fonts="false", even though its own font list no longer used Open Sans. v12 makes no font requests: text uses --font-sans and --font-mono, which default to the operating system’s UI and monospace fonts.

  • The load-fonts attribute is removed. You can delete load-fonts="false" from your markup; leaving it in has no effect.
  • To keep a brand font (Open Sans or any other), load it in your page and set --font-sans / --font-mono on rapi-doc. See Typography & Brand Fonts.

The theme presets are reduced to five, each with a dark and a light palette: ember (default), carbon, cobalt, jade and indigo. See Pre-built Themes.

v11 v12
amber (and no attribute) ember: same #f76b39 accent, neutral charcoal surfaces instead of blue-grey
graphite carbon: same accents, near-black surfaces in dark mode
blue cobalt (matte steel blue; pass theme="#2563eb" for the old electric blue)
emerald jade
violet indigo
rose, slate, modern, default removed; pass a hex code (theme="#e11d48") for an accent of your own

The old names and a bare #f76b39 are no longer special: an unknown name falls back to ember, and any hex code is a custom accent over the default surfaces.

Base surfaces also changed: dark --background is #1f1f23 with --foreground: #d4d4d8 (was a blue-grey oklch surface with #cccccc), and light --foreground is #27272a (was #444444). color-scheme="system" now derives its light-mode cards, borders and muted colors from the background and foreground exactly like color-scheme="light".