javascript 37 lines · 6 steps

Building an accessible Sidebar in React

A data-driven nav that computes its own active state and mirrors it into both classes and ARIA.

Explained by highlit
1import { NavLink, useLocation } from 'react-router-dom';
2 
3const NAV_ITEMS = [
4 { to: '/', label: 'Dashboard', end: true },
5 { to: '/projects', label: 'Projects' },
6 { to: '/team', label: 'Team' },
7 { to: '/settings', label: 'Settings' },
8];
9 
10export default function Sidebar() {
11 const { pathname } = useLocation();
12 
13 const isActive = (to, end) =>
14 end ? pathname === to : pathname === to || pathname.startsWith(`${to}/`);
15 
16 return (
17 <nav className="sidebar" aria-label="Main navigation">
18 <ul>
19 {NAV_ITEMS.map(({ to, label, end }) => {
20 const active = isActive(to, end);
21 return (
22 <li key={to}>
23 <NavLink
24 to={to}
25 end={end}
26 aria-current={active ? 'page' : undefined}
27 className={`nav-link${active ? ' nav-link--active' : ''}`}
28 >
29 {label}
30 </NavLink>
31 </li>
32 );
33 })}
34 </ul>
35 </nav>
36 );
37}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Driving navigation from a data array keeps markup uniform and makes adding links a one-line change.
  2. 2Prefix matching with an `end` escape hatch lets parent routes stay highlighted for nested children while the index route matches exactly.
  3. 3Reflecting active state into `aria-current` alongside a CSS class keeps the UI accessible, not just visually styled.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Building an accessible Sidebar in React — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code