Side Nav
Sourcecomponents/SideNav.astro
The rail
The sticky dashboard sidebar — a logo header, grouped rows (each an optional label and a set of Side Nav Items), a Divider, and a User Chip at the foot. It sticks to the viewport and scrolls internally when the list is tall.
Switch viewport, or scroll the preview — the rail stays put while the content scrolls.
Built from
- Side Nav Item — each row: a stroke icon, a label, and the active state.
- Divider — the hairline above the foot.
- User Chip — the signed-in identity, itself built from Avatar.
Behaviour
- Sticky —
position: sticky; top: 0at100svh; the row list scrolls inside while the logo and user chip stay pinned. - Icons are passed inline per item (an SVG string,
fill="none"stroke="currentColor") so each takes its row's colour — including violet on the active row. - ≤900px — the rail unpins and spans full width with a bottom border, for a top-of-page strip.
Props
| Prop | Type | Default | Notes |
|---|---|---|---|
groups | NavGroup[] | — | The sections. Each { label?, items: { label, href, icon?, active? }[] }. Required. |
user | User | — | Foot identity — { name, role?, avatarSrc?, initials?, href? }. Omit to hide. |
logo | string | '/img/logo-dark.svg' | The header logo (dark, for the cream rail). |
logoHref | string | '/' | Where the logo links. |
logoAlt | string | 'Alchemy Zurich' | Logo alt text + brand aria-label. |
Usage
Give it groups and a user. Mark the current page with active: true on its item. Place it as the first child of a flex shell beside your content.
---
import SideNav from '../components/SideNav.astro';
const eye = '<svg viewBox="0 0 20 20" fill="none">…</svg>'; // inline stroke icon
const groups = [
{ label: 'Aktive Projekte', items: [{ label: 'Essential Brand Projekt', href: '/p/essential', icon: eye }] },
{ label: 'Generell', items: [
{ label: 'Website', href: '/website', icon: globe },
{ label: 'Formulare', href: '/forms', icon: doc },
] },
{ label: 'Hilfe', items: [
{ label: 'Chat', href: '/chat', icon: chat },
{ label: 'Alchemy Shop', href: '/shop', icon: shop, active: true },
] },
];
const user = { name: 'Alex Morgan', role: 'Designer', initials: 'AZ' };
---
<SideNav {groups} {user} /> Rules
Do
Group rows under short section labels — one word or two.
Mark exactly one item active — the page you're on.
Don't
Mix this app rail with the site top Navigation — one or the other.
Letter-space the section labels — labels stay at 0.