Per-UI WithConfiguration for the bundled docs UIs (v0.7.0)#103
Merged
Conversation
Each ui/* sub-package's WithUI now takes variadic options, with a shared WithConfiguration(map[string]any) that forwards UI-native configuration to the page without forking the template or its CSP. The map is rendered once, in the docs handler, into the carrier each UI understands: a data-configuration attribute for Scalar, a non-executable <script type="application/json"> block read by a static, hash-pinned initializer for Swagger UI and Redoc, and <elements-api> attributes for Stoplight. A new exported Config.UIConfig field carries it, and a small internal/uiopt package holds the shared option plumbing. The UIs also disable, by default, the features that cannot work under the strict docs CSP, so the page has no dead chrome: Scalar's Ask AI and Generate MCP (they call scalar.com) and its external fonts, and Swagger UI's spec-validator badge (validator.swagger.io). These are plain defaults a caller's WithConfiguration overrides at the top level; relaxing the CSP so a re-enabled feature can reach its service is WithDocsSecurityHeaders(false) or WithCSP. Swagger's inline-init hash is re-pinned, and Redoc gains one (it now boots via Redoc.init rather than the spec-url web component). Separately, the spec endpoint now sends Content-Disposition: inline with a filename, so a direct download gets a sensible name while the document still renders in the browser.
8fe5bbb to
3304db0
Compare
FumingPower3925
added a commit
that referenced
this pull request
Jun 19, 2026
Each ui/* sub-package's WithUI now takes variadic options, with a shared WithConfiguration(map[string]any) that forwards UI-native configuration to the page without forking the template or its CSP. The map is rendered once, in the docs handler, into the carrier each UI understands: a data-configuration attribute for Scalar, a non-executable <script type="application/json"> block read by a static, hash-pinned initializer for Swagger UI and Redoc, and <elements-api> attributes for Stoplight. A new exported Config.UIConfig field carries it, and a small internal/uiopt package holds the shared option plumbing. The UIs also disable, by default, the features that cannot work under the strict docs CSP, so the page has no dead chrome: Scalar's Ask AI and Generate MCP (they call scalar.com) and its external fonts, and Swagger UI's spec-validator badge (validator.swagger.io). These are plain defaults a caller's WithConfiguration overrides at the top level; relaxing the CSP so a re-enabled feature can reach its service is WithDocsSecurityHeaders(false) or WithCSP. Swagger's inline-init hash is re-pinned, and Redoc gains one (it now boots via Redoc.init rather than the spec-url web component). Separately, the spec endpoint now sends Content-Disposition: inline with a filename, so a direct download gets a sensible name while the document still renders in the browser.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Milestone v0.7.0. Closes #101 and #102.
Per-UI
WithConfiguration(#101)Each bundled UI sub-package's
WithUInow accepts variadic options, with a sharedWithConfiguration(map[string]any)that forwards UI-native configuration without forking the template or its CSP:newDocsCoreviahtml/templateinto the carrier each UI understands: Scalardata-configurationattribute; Swagger UI & Redoc a non-executable<script type="application/json">block read by a static, hash-pinned initializer; Stoplight<elements-api>attributes.Config.UIConfig; sharedinternal/uiopt(Apply/Configuration/Merge).WithUI()calls still compile (verified from an external module).CSP-safe defaults
The UIs now disable, by default, the features that can't work under the strict docs CSP, so there's no dead chrome: Scalar's Ask AI / Generate MCP (call scalar.com) + external fonts, and Swagger UI's validator badge (validator.swagger.io). All overridable via
WithConfiguration(top-level); relax the CSP withWithDocsSecurityHeaders(false)/WithCSP. Swagger's inline-init sha256 is re-pinned; Redoc gains one (it now boots viaRedoc.init).Content-Dispositionon the spec endpoint (#102)serveSpecnow sendsContent-Disposition: inline; filename="openapi.json"(and.yaml) — a sensible save-as name while still rendering in-browser.Verification
gofmt/go build/go vet/-race/golangci-lintall clean across 17 packages; zero runtime deps.UIConfig, CSP parity with config.