Field notes/Field note

Field note

The sidebar nobody noticed

The new docs pages have a sticky left nav and a sticky right TOC. We did not invent the pattern — we picked it. The post is about which IA layers to invent and which to copy wholesale from a vendor twenty times your size.

Denys Kuzin··4 min read·field-noteiadocsmethodology

The new drill-in pages at /ship/docs/process/states and /lighthouse/docs/quickstart shipped two weeks ago. Three columns: nav rail on the left, article in the centre, in-page table of contents on the right. Both rails sticky. The reaction we got — internally and from the first half-dozen pilot operators who hit them — was no reaction. Nobody mentioned it. Two people sent us heading deep-links the day after, which means they used the TOC, scrolled, copied a URL fragment, and didn't think about it.

That is the success. The pattern is so familiar that it landed without being noticed.

What we picked

We did not invent the layout. The three-column docs page — left nav, centre article, right TOC, both sides sticky — is the convention Linear, Vercel, and Stripe have all converged on, and which a long tail of smaller docs sites have copied from them. We copied it from them too. The CSS is sticky positioning and a max-height. The right rail is a list rendered from the article's headings. There is nothing novel about any of it.

Three checks made us comfortable picking rather than designing:

The pattern is mature. When three independent docs teams operating at very different scales settle on the same control surface, the design exploration is over. The shape works. Spending a week of our own design budget re-deriving it would have produced the same shape, slightly worse, on a longer timeline.

The reader already knows the controls. A developer landing on our docs page from a Google result has used this layout hundreds of times this year. The left rail is the section index. The right rail is this page. Clicking a heading on the right scrolls. Nothing about that needs onboarding. The closer our IA matches the IA they already have in their head, the more attention they have left for the content.

The implementation is mostly free. Sticky CSS plus an IntersectionObserver hook is a single afternoon. There is no library, no framework lock-in, no design system tax. The cheapest version of the pattern produces the canonical version of the pattern.

What we did add

Two micro-customisations, both at the detail level rather than the pattern level.

The first: slug-to-anchor generation on every heading in our markdown pipeline. An H2 titled "Stage transitions" becomes <h2 id="stage-transitions">, with the slug computed by the same kebab-caser we use for ticket titles. That makes every heading deep-linkable without the author having to write the anchor by hand. It also means the right-rail TOC and the URL fragment use the same string, which is the kind of consistency you only notice when it's missing.

The second: the right rail's "you are here" highlight is driven by an IntersectionObserver watching all H2 and H3 elements in the article. As you scroll, the entry whose heading is closest to the top of the viewport gets the active state. It's the same trick the bigger docs sites use, give or take a few lines of logic about handling the case where two headings are in view at once. Ours preferences the lower one, which matches how readers actually parse "where am I" while scrolling down.

Both of those are details. Neither changes the pattern. A reader who's used the bigger sites will recognise the behaviour without thinking.

The general rule

We have a working heuristic now about when to invent and when to pick.

Invent at the layers where you'd lose otherwise. The process model — what a Ship "stage" means, how routines fire on transitions, how the agent reads a routine and produces a turn — is ours. Nobody else has it. If we copied somebody else's shape there, we'd be shipping their product. The evals shape, the cross-product ribbon between Ship and Lighthouse, the way the navigator's chat memory is keyed — those are differentiators, and they have to be designed from the problem.

Pick at the layers where the field has converged. Docs nav. Blog cards. Status pages. Login flows. Pagination. Modal dismissal behaviour. Form-error placement. These are solved. The people landing on those surfaces have muscle memory we can either fight or use. Fighting it costs design hours and onboarding load, and the prize for winning is a slightly different version of the same thing.

The same logic ran through our colour change two weeks earlier — see champagne over teal. The accent was a positioning lever; we invested. The docs layout is not a positioning lever; we copied.

There is a tax. If the convention shifts — if the three reference sites collectively move to a different layout in eighteen months — we will look slightly dated until we re-copy. We are accepting that tax. It is smaller than the cost of having spent the original week designing our own version, and smaller still than the cost of asking every reader to learn our particular take on a docs nav.

What we're still tempted to invent

The honest answer is the admin surfaces. The integrations page, the secrets page, the workspace settings — those are places where we keep reaching for novel layouts because the underlying domain feels novel to us. It is not novel to the operator. They have configured GitHub Apps and rotated tokens on a dozen other products this year. The convention is there. We should pick it.

The long read

This is one field note. The full argument lives in the book.

Read the book