Skip to content

Theming

wiki edited this page Sep 4, 2026 · 1 revision

Theming

Two themes ship with the module, and you can register your own.

swagger.WithSwagger(swagger.NewConfig(
	swagger.WithDefaultTheme("dark"),
))
Name
"default" stock Swagger UI
"dark" the bundled dark theme

Both stylesheets are embedded; neither is fetched at runtime.

The dark theme

Method colours are tuned for a dark background — including OPTIONS (#a1a1a1) and TRACE (#e1e1e1), which stock Swagger UI does not distinguish well against dark.

That matters here more than it might elsewhere, because the Rex router answers OPTIONS itself from its Allow set, so OPTIONS shows up in documents more often than in a typical Swagger UI deployment.

A custom theme

//go:embed themes/corporate.css
var corporateCSS []byte

app := rex.New(swagger.WithSwagger(swagger.NewConfig(
	swagger.WithCustomTheme("corporate", corporateCSS),
	swagger.WithDefaultTheme("corporate"),
)))

Served at <ServePath>/assets/themes/corporate.css. Registering the same name twice overwrites the previous CSS.

Custom themes are additional stylesheets, layered over the base Swagger UI stylesheet — so a theme overrides what it names and inherits the rest. You do not have to restyle the whole UI to change a colour.

Writing one

Start from the class names Swagger UI already uses:

/* Brand the header. */
.swagger-ui .topbar {
  background-color: #12233f;
}
.swagger-ui .topbar .download-url-wrapper {
  display: none; /* hide the "explore" URL box */
}

/* Method colours. */
.swagger-ui .opblock.opblock-post   { border-color: #16a34a; background: rgba(22,163,74,.08); }
.swagger-ui .opblock.opblock-delete { border-color: #dc2626; background: rgba(220,38,38,.08); }

/* The Required Authorization panel this module adds. */
.swagger-ui .required-roles-panel { border-left: 3px solid #f59e0b; }

Two practical notes:

  • Prefix with .swagger-ui. The UI's own rules are specific; unprefixed selectors usually lose.
  • Load the page and read the DOM. Swagger UI's class names are stable across patch releases but not documented; inspecting is faster than guessing.

Serving a theme from elsewhere

WithCustomTheme embeds bytes, which is the point — the CSS ships with the binary and cannot fail to load. If you would rather serve a stylesheet from your own asset pipeline, register a route for it and reference it from a custom theme that only contains an @import. Note that this reintroduces a runtime fetch and the failure mode that goes with it.

Which theme loads

DefaultTheme is the theme applied on first load. Any name registered with WithCustomTheme is valid, as are "default" and "dark".

Setting DefaultTheme to a name that was never registered leaves the page without a theme stylesheet — the UI still works, styled by the base CSS only.

Clone this wiki locally