Scalar UI
openapi.SetupDocsEndpoints serves a Scalar reference page that reads your generated spec. Readers get a searchable endpoint list, request and response schemas, and a client for trying calls.
Serve it
openapi.SetupDocsEndpoints(app)
| Path | Contents |
|---|---|
/docs | The Scalar reference page |
/openapi.json | The generated document |
/docs/ | A permanent redirect to /docs |
All three are registered Public(), so they work without a token even when the rest of the app requires one.
Configure it
openapi.SetupDocsEndpoints(app, openapi.ScalarConfig{
Title: "Orders API",
Theme: "deepSpace",
Layout: "modern",
DarkMode: true,
ShowSidebar: true,
HideModels: false,
FavIcon: "/favicon.ico",
})
| Field | Values | Default |
|---|---|---|
Title | Any string, used as the page title | API Documentation |
Theme | default, alternate, moon, purple, solarized, bluePlanet, saturn, kepler, mars, deepSpace | default |
Layout | modern, classic | modern |
DarkMode | bool | false |
ShowSidebar | bool | true in the default config |
HideModels | bool, hides the schema list | false |
CustomCSS | CSS injected into the page | empty |
FavIcon | URL of a favicon | empty |
openapi.DefaultScalarConfig() returns the defaults if you want to start from them and change one field.
Use custom paths
openapi.ServeScalar(app, "/openapi.json", "/reference", openapi.ScalarConfig{
Title: "Orders API",
})
The first path serves the spec, the second serves the UI. The UI fetches the spec path from the browser, so it has to be reachable by whoever opens the page.
Restrict who can read the docs
Public docs are convenient internally and often unwanted in production. Two straightforward options.
Serve them only outside production:
if os.Getenv("APP_ENV") != "production" {
openapi.SetupDocsEndpoints(app, cfg)
}
Or gate them with middleware on a group, keeping the paths but requiring a credential:
docs := app.Group("/internal").Use(basicAuth(os.Getenv("DOCS_USER"), os.Getenv("DOCS_PASS")))
docs.GET("/openapi.json", specHandler).Public()
docs.GET("/docs", uiHandler).Public()
Because ServeScalar registers on the app rather than a group, this variant means writing the two small handlers yourself, as shown in OpenAPI.
Style it
CustomCSS is injected into a <style> tag, which is enough to match a brand:
openapi.SetupDocsEndpoints(app, openapi.ScalarConfig{
Title: "Orders API",
DarkMode: true,
CustomCSS: `
:root {
--scalar-color-accent: #00add8;
--scalar-font: "Inter", system-ui, sans-serif;
}
`,
})
Helper functions exist for building a config in steps:
cfg := openapi.DefaultScalarConfig()
openapi.ApplyScalarOptions(&cfg,
openapi.WithCustomTheme("moon"),
openapi.WithDarkMode(true),
openapi.WithLayout("classic"),
)
openapi.SetupDocsEndpoints(app, cfg)
Know the constraints
cdn.jsdelivr.net. A machine with no internet access, or a strict Content-Security-Policy, will render an empty page. If either applies, serve the spec with ezz and host the viewer yourself, or vendor the bundle and serve it from your own static assets.The spec is regenerated on every request to the spec path. That is fine for a documentation endpoint, but do not put it on a hot path or a health check.