Skip to content

docs: restructure navigation around Bruno's products, and go full width - #161

Closed
anthonyd-bruno wants to merge 3 commits into
usebruno:mainfrom
anthonyd-bruno:docs/restructure-by-product
Closed

docs: restructure navigation around Bruno's products, and go full width#161
anthonyd-bruno wants to merge 3 commits into
usebruno:mainfrom
anthonyd-bruno:docs/restructure-by-product

Conversation

@anthonyd-bruno

Copy link
Copy Markdown
Collaborator

Why

Feedback was that the docs are hard to navigate — it isn't easy to find what you need from the sidebar, and it isn't easy to tell what the different parts of Bruno actually are.

The v4 sidebar was a single flat list of six generic buckets (Getting Started, Core Features, API Tools, Developer Tools, License Management, Advanced Guides) that mixed the products together. The CLI, the VS Code extension and the API documentation all lived under "Developer Tools" alongside Bru Lang and the converters.

What changed

1. Navigation restructured around Bruno's products (docs.json)

Those buckets are replaced with Mintlify tabs, one per product:

Get Started | API Client | CLI | API Docs | VS Code Extension | Reference | Licensing

The four product tabs are the spine. The other three exist because the content has to live somewhere: Get Started is the cross-product onboarding path, Reference holds the genuinely shared material (Bru Lang, OpenCollection YAML, converters), and Licensing is orthogonal to all four. They're ordered so the four products read as a contiguous block.

Beyond the regrouping:

  • CLI is promoted from a subgroup to a tab and resplit into Overview / Run Collections / Configuration / CI/CD (it was a 10-item flat list).
  • "Git Providers" folds into "Git & Collaboration" — it was a two-page group sitting beside the real Git docs.
  • advanced-guides/visualize is "Response Visualization", so it moves under Response Data & Cookies. That retires the one-page "Advanced Guides" group.
  • get-started/configure/* becomes "Settings" under API Client.

One new page, api-client/overview.mdx, gives the API Client tab a landing page. It cross-links the other three products so each part of Bruno is discoverable from the others.

No files were moved and no page paths changed, so every existing URL still resolves and no redirects are needed.

2. Nav tabs span the full header width (style.css, new file)

The tab row is a shrink-to-fit flex container, so seven tabs bunched against the left gutter — at 1440px it measured 796px inside 1344px of available space. Letting it grow and distributing the slack with justify-content: space-between divides the leftover width into six identical gaps.

3. The docs shell is full width (style.css)

Mintlify centres the whole shell inside a max-w-8xl (1472px) box, leaving 224px of dead margin per side at 1920px and 544px at 2560px. Two elements carry that cap — the navbar rail and the wrapper around the sidebar/content/TOC — and both are released.

docs.json has no content-width option (styling accepts only eyebrows and codeblocks), and the native escape hatches are per-page frontmatter mode: "custom" / "wide", which drop chrome we want and would need pasting into every .mdx. So CSS is the only route.

Mintlify auto-loads a root style.css — the same mechanism that already loads reo.js and webinar-card.js.

Verification

Measured with Puppeteer against mint dev, both themes, across /introduction/getting-started, /bru-cli/overview, /license-overview, /send-requests/REST/rest-api and /bru-cli/commandOptions.

Nothing lost in the restructure. All 196 pages currently in the v4 nav are still there, each exactly once, every one resolving to a file. v2 and v3 navigation are byte-identical — they're legacy version snapshots and are deliberately untouched.

Tab spacing — gap spread is exactly 0.00px at every width, i.e. all six gaps identical:

viewport each gap bar span
1024 45.93px 48 → 976 flush both edges
1440 115.26px 48 → 1392 flush both edges
1920 120.59px* 272 → 1648 flush both edges

* before the full-width change; 195.3px after, since the rail is no longer capped.

Full width — a measured no-op up to 1472px, so most laptops see no change at all:

viewport content column sidebar x TOC right edge
1440 688.8px 32 1408 (no-op)
1472 720.8px 32 1440 (no-op)
1473 721.8px 32 1441 (first change)
1920 1168.8px 32 1888
2560 1808.8px 32 2528
  • No horizontal overflow at any width (scrollWidth === clientWidth throughout).
  • Mobile untouched — the tab bar is display:none below 1024px, and content measures 460px/760px at 500px/800px viewports, unchanged.
  • The underline indicator is unchanged from baseline (100.16px Get Started, 46.01px CLI, 88.32px Licensing).
  • mint validate passes. mint broken-links reports the same 99 pre-existing broken links as main — none new.

Known costs on very wide screens

Both are documented inline in style.css and both are dials that can be turned:

  • Prose measure grows from 78 characters to 124 at 1920px and 198 at 2560px. Capping the content column instead was built and measured — it strands the TOC across a void of up to 1461px at 3440px, and capping prose alone gives the page two different right margins. Leaving the shell uncapped is the only variant where every element keeps a single shared right edge.
  • Card grids top out at 2 columns (a Mintlify container query), so cards inflate rather than reflow past ~2560px.

Notes for review

  • Rebased onto main after Server Side Events  #156 landed; send-requests/REST/sse is carried into the new REST group in its original position. Verified zero pages dropped relative to main.
  • docs.json doesn't satisfy npm run lint, but it didn't on main either — I preserved the existing formatting rather than bury the restructure in a whole-file reformat. style.css and api-client/overview.mdx are both prettier-clean.
  • The 99 pre-existing broken links (mostly doubled /images/images/... paths and stale /import-export-data/... links in variables/*) are untouched here and worth a separate cleanup.

🤖 Generated with Claude Code

anthonyd-bruno and others added 3 commits August 5, 2026 10:47
Feedback was that the sidebar made it hard to find things and hard to
tell what the different parts of Bruno are. The v4 sidebar was a single
flat list of six generic buckets (Getting Started, Core Features, API
Tools, Developer Tools, License Management, Advanced Guides) that mixed
products together — the CLI, VS Code extension, and API documentation
all lived under "Developer Tools" alongside Bru Lang and converters.

Replace those buckets with Mintlify tabs, one per product:

  Get Started | API Client | CLI | API Docs | VS Code Extension
  | Reference | Licensing

Notable moves:
- Bruno CLI is promoted from a subgroup to its own tab, split into
  Overview / Run Collections / Configuration / CI/CD.
- API Docs and the VS Code extension become top-level tabs.
- "Git Providers" folds into "Git & Collaboration".
- advanced-guides/visualize moves under Response Data & Cookies, which
  is what it documents, retiring the one-page "Advanced Guides" group.
- get-started/configure/* becomes "Settings" under API Client.

Add api-client/overview.mdx as the API Client landing page; it also
cross-links the other three products so each part of Bruno is
discoverable from the others.

No files were moved and no page paths changed, so every existing URL
still resolves and no redirects are needed. All 195 previously
navigable pages remain in the nav, each exactly once. `mint validate`
passes and `mint broken-links` reports the same 99 pre-existing broken
links as main — none new.

v2 and v3 navigation are left untouched as legacy snapshots.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The tab row is a shrink-to-fit flex container, so the seven product tabs
bunched against the left gutter — at a 1440px viewport .nav-tabs measured
796px inside 1344px of available space, leaving ~548px of dead air on the
right.

Let .nav-tabs grow to fill its px-12 rail and hand the free space to
justify-content: space-between. Tabs keep their intrinsic widths, so the
leftover width is divided equally between the six gaps.

Measured (light + dark, /introduction/getting-started, /bru-cli/overview
and /license-overview, via puppeteer against the dev server):

  width  gaps (each)  bar span
  1024   45.93px      48 -> 976     flush both edges
  1280   88.59px      48 -> 1232    flush both edges
  1440   115.26px     48 -> 1392    flush both edges
  1920   120.59px     272 -> 1648   flush both edges
  2560   120.59px     592 -> 1968   flush both edges

Gap spread is exactly 0.00px at every width — all six gaps identical. The
first tab stays flush with the logo gutter and the last tab lands on the
header controls' alignment line. The navbar's existing max-w-8xl ancestor
caps the row at 1376px, so gaps self-limit at ~121px on ultrawide rather
than growing without bound.

Deliberately minimal — two declarations, nothing applied to
.nav-tabs-item:
- The underline indicator needs no CSS. Anchors keep their intrinsic
  width, so each indicator still spans its own tab box; measured
  identical to baseline (100.16px Get Started, 46.01px CLI, 88.32px
  Licensing) in both themes.
- The rule is a no-op once free space runs out, so today's shrink/wrap
  fallback is preserved. Verified byte-identical to baseline at 1024px
  with root font-size 24px (981.4px bar, last tab right edge 1053.4px
  both with and without the rule). Approaches adding min-width:0,
  overflow-x:auto, flex:0 0 auto or per-item padding were tested and
  rejected: each converts that reachable fallback into silently clipped
  or hidden tabs under browser font scaling.
- Scoped to min-width:1024px to match the wrapper's `hidden lg:flex`, so
  the mobile dropdown is untouched (confirmed hidden at 800px and
  1023px). The breakpoint is px on purpose — Tailwind compiles `lg` to
  px, verified at root font sizes 12/16/20px.

Mintlify auto-loads a root style.css, the same mechanism that already
loads reo.js and webinar-card.js. `mint validate` passes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Mintlify centres the whole shell — sidebar, article and table of contents
— inside a max-w-8xl (92rem = 1472px) box with mx-auto. Past that width
the box stops growing and the remainder becomes equal dead margins: 224px
per side at 1920px, 544px per side at 2560px, with nothing rendered in
them.

Two elements carry the cap and both must be released or the navbar ends
up on a different grid from the body: the navbar rail (a plain
`max-w-8xl` utility) and the wrapper around #sidebar/#content-area/the
TOC (the same cap written through Mintlify's per-page `mode` peer
variants). A single `[class*="max-w-8xl"]` selector matches both without
coupling to either element's position in the tree.

docs.json has no content-width option — `styling` accepts only `eyebrows`
and `codeblocks` — and the native escape hatches are per-page frontmatter
`mode: "custom"` (drops sidebar and TOC) and `mode: "wide"` (drops the
TOC), which remove chrome we want and would need pasting into every .mdx.
So CSS is the only route.

Measured on /send-requests/REST/rest-api:

  viewport   content column   sidebar x   TOC right edge
  1280       528.8px          32          1248   (no-op)
  1440       688.8px          32          1408   (no-op)
  1472       720.8px          32          1440   (no-op)
  1473       721.8px          32          1441   (first change)
  1920       1168.8px         32          1888
  2560       1808.8px         32          2528

No media query is needed: the rule releases the cap exactly where the cap
binds, so it is a measured no-op at every width up to 1472px — most
laptops see no change at all. Mobile is untouched (content 460px at 500px
viewport, 760px at 800px, both unchanged). No horizontal overflow appears
at any width.

The rule caps nothing, so every element keeps a single shared right edge.
Three capping variants were built and measured and all scored worse:
capping the content column strands the TOC across a void of up to 1461px
at 3440px, and capping prose alone gives the page two different right
margins that read as a misalignment bug.

Interaction with the nav-tab rule: the cap used to bound the tab rail at
1376px, so its gaps settled at ~121px. Uncapped they track the viewport —
195px at 1920, 302px at 2560. Gaps remain exactly equal (spread 0.00px at
every width) and the rail stays flush with the wordmark and header
controls, so it is left unbounded; every way of bounding it reinstates
the dead margin this change removes.

Known costs on very wide screens, documented in style.css: prose measure
grows from 78 characters to 124 at 1920 and 198 at 2560, and Mintlify's
card grids top out at 2 columns so cards inflate rather than reflow.
Both are dials that can be turned if they become the complaint.

`mint validate` passes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@anthonyd-bruno

Copy link
Copy Markdown
Collaborator Author
Screenshot 2026-08-05 at 10 54 03 AM Screenshot 2026-08-05 at 10 54 13 AM Screenshot 2026-08-05 at 10 54 17 AM Screenshot 2026-08-05 at 10 54 21 AM Screenshot 2026-08-05 at 10 54 24 AM Screenshot 2026-08-05 at 10 54 26 AM Screenshot 2026-08-05 at 10 54 40 AM

@anthonyd-bruno

anthonyd-bruno commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator Author

Closing in favor of #163 — same branch (542721c), pushed to this repo instead of my fork so Mintlify can generate a preview deployment. The Mintlify GitHub app can't build against fork PRs, which is why no preview or checks ever appeared here. Screenshots above still apply.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant