Mycelium

The Rest

Navigation Is a Contract

Every way of moving a person through an interface is a promise about where they'll land and what will still be true when they get there. A sidebar link, a tab, a breadcrumb, a back button — each one swears something before it's ever touched. Keep the promise and the person always knows where they are. Break it enough times and they stop trusting the building, the way you stop trusting a house where the doors don't lead where doors should lead.

Navigation is the most promise-dense surface there is, and the promises live at two levels: the individual elements, and the shell that holds them. (The deepest one — the URL — gets its own chapter. It's earned it.)

The elements don't mean the same thing

A navigation item — sidebar, top bar, menu — promises to move you to a different place. Not a different view of the same place. A different context, where what was true on the last screen stops being true and a new set of truths begins. Which is exactly why the sidebar item that quietly toggles a panel, or filters a list, or expands some inline content, is a small betrayal: it wears the clothes of going somewhere and then keeps you precisely where you were. The stronger the expectation of movement, the more disorienting the lie.

A tab promises the opposite: you stay put, and only the visible slice changes. Same page, same record, same context — a different face of it. That's a fundamentally different promise from a nav item, which is why the two must never look alike. Dress a tab like a nav item and the person can't tell whether clicking will move them or hold them — the one question the visual form exists to answer before the click. And tabs make a second promise just by being tabs: that they're peers, all at the same level. The tab that wanders off to another context while its siblings stay home breaks both promises at once.

Breadcrumbs promise to show you where you are in a hierarchy and let you climb it. Location first, navigation second. They go up. They don't go sideways — so a breadcrumb in a flat structure with no hierarchy to show is decoration pretending to be orientation, and a breadcrumb used as the main way to move between sections is a ladder pressed into service as a hallway.

A back button promises to reverse your last step — to return you to wherever you actually came from, whatever that was. That's a promise about your journey, not about the page's parentage. When a "back" button instead jumps to a fixed parent route, it's usually the same place you came from — until it isn't, and then the person is standing somewhere they never asked to be, displaced by a button that promised return.

Under all of these sits the contract violated most often: navigation moves you; actions do something. A button in the nav bar that submits a form, a nav item that fires a modal, a "New record" link that's secretly a create action — each one blurs the line the person leans on to know what can be undone. Navigation you can walk back. Actions, often, you can't. Wear the clothes of moving while doing something irreversible, and you've quietly taken away the person's sense of what's safe to try.

Scope has to match the shell

The elements sit inside a shell, and a navigation item's scope should match the level of the shell that holds it.

Global navigation — the logo, product switching, account, notifications — is true no matter where you are, so it belongs in the first-level shell, the top bar. Local navigation is true only inside the section you're in, so it belongs in the sidebar, and it should change when you move to a different part of the app; a sidebar that shows the identical items everywhere has quietly promoted local navigation to global — a lie about what's always available. Contextual navigation — breadcrumbs, in-page tabs, related links — is true only for the record in front of you, and belongs in the page itself.

Mix the scopes and you mislead. Put local navigation in the global shell and you've told the person that section-specific things are universal. Put record-level actions in the sidebar and you've told them a one-record operation applies to the whole section. Each mismatch chips at the map they're building of your app.

The honest test is the mobile collapse. When the sidebar folds into a burger inside the top bar, the layout is confessing the real hierarchy: the top bar is the global shell, the sidebar is its child. So watch what survives the fold. Whatever stays reachable was genuinely global; whatever collapses with the sidebar was local. And a "global" item that lived in the sidebar and then vanishes on mobile was never global at all — and the people on phones are the ones who pay for the mislabel.

Get the elements and the shell honest, and a person can move through the whole system without ever having to think about moving. But there's a deeper record of where they are than anything painted on the screen — one that survives a refresh, travels between devices, and can be handed to someone else intact. That's the URL. And it keeps its own promises.