Context
We mount Redoc with default visuals (Montserrat/Roboto, default sidebar, no logo). Multiple downstream projects ship public docs at /api/docs and would benefit from a polished default. This is a devkit-only enhancement — no per-project patches required.
Scope
1. Polish default theme in lib/services/express.js
Pass a theme object to redocOptions with:
- Typography: Inter (body) + JetBrains Mono (code), replacing Montserrat/Roboto
- Sidebar: tighter spacing, drop
text-transform: uppercase on group items
- Code blocks: refined background, softer contrast
- Spacing: tighter rhythm
- No hardcoded brand color — keep Redoc default neutral
2. Wire existing config
Already wired: config.app.title, config.app.description. Add:
info.x-logo from config.app.url (href) + optional config.app.logo (URL); if config.app.logo absent, no logo (no regression)
3. Optional downstream override
Deep-merge config.docs.redocTheme (if present) with devkit defaults:
const theme = _.merge({}, defaultTheme, config.docs?.redocTheme || {});
Downstream wanting brand color adds it in their own config — zero devkit edit.
4. Minimal custom CSS
≤ 30 lines for callouts/tables/blockquotes — only what theme schema can't cover. Injected via theme.customCss.
Out of scope
- Per-project branding (downstream concern via override mechanism above)
- Dark mode UI toggle (V2 if requested)
x-codeSamples injection (per-endpoint, downstream .yml concern)
Effort
~2h impl + 1h test. Single PR.
Downstream impact
All downstream auto-benefit on next /update-stack. Backward-compat: absent config.docs.redocTheme = devkit defaults apply.
Refs
Context
We mount Redoc with default visuals (Montserrat/Roboto, default sidebar, no logo). Multiple downstream projects ship public docs at
/api/docsand would benefit from a polished default. This is a devkit-only enhancement — no per-project patches required.Scope
1. Polish default theme in
lib/services/express.jsPass a
themeobject toredocOptionswith:text-transform: uppercaseon group items2. Wire existing config
Already wired:
config.app.title,config.app.description. Add:info.x-logofromconfig.app.url(href) + optionalconfig.app.logo(URL); ifconfig.app.logoabsent, no logo (no regression)3. Optional downstream override
Deep-merge
config.docs.redocTheme(if present) with devkit defaults:Downstream wanting brand color adds it in their own config — zero devkit edit.
4. Minimal custom CSS
≤ 30 lines for callouts/tables/blockquotes — only what
themeschema can't cover. Injected viatheme.customCss.Out of scope
x-codeSamplesinjection (per-endpoint, downstream.ymlconcern)Effort
~2h impl + 1h test. Single PR.
Downstream impact
All downstream auto-benefit on next
/update-stack. Backward-compat: absentconfig.docs.redocTheme= devkit defaults apply.Refs