Module 1: Routes and containers · Lesson 2 of 7 · 3 min read
Router: the URL is state too
Route tables, dynamic segments, catch-alls and the share of state that belongs in the address bar, briefed so an agent's links still work.
What a router actually does
The Router doc breaks it into five
steps: intercept the link click (event.preventDefault()), update the address
bar with history.pushState(), match the new URL against a route table
(/users/:id matches /users/123), unmount the old component and mount the
new one, and leave the store, context and global JavaScript state intact. The
back and forward buttons keep working through popstate.
The Angular template’s whole route table,
templates/chota-angular-ngrx/src/app/app.routes.ts, is two entries:
export const routes: Routes = [
{ path: '', component: HomePageComponent },
{ path: '**', redirectTo: '' },
];
The second line is the catch-all whose absence the doc lists as a common
mistake: without it, an unknown URL renders a blank page. Notice also what the
route points at — a page in src/pages, which composes containers. The router
decides which page; it never reaches into the store itself.
The mistakes that ship
- A bare
<a href>for internal navigation instead ofLink,routerLinkor<router-link>. Every click becomes a full reload, the white flash returns and the store is rebuilt from nothing. - Partial matching — React Router v5’s forgotten
exactrendered two routes at once. - No 404 route.
The skill adds the three a reviewer most often misses: no focus management or route-change announcement for screen-reader users, no scroll restoration, and no loading state while a lazily loaded route chunk downloads.
Filters belong in the URL
The doc’s promise of “shareable URLs for specific app states” is the line that
matters for product work. A filtered list whose filters live in component state
cannot be linked, refreshed or reached with the back button. The practice
question moves them: toQuery and fromQuery round-trip a search term,
categories, sort and page. Keys come out in a fixed order so the same filters
always produce the same, cacheable string; values equal to their default are
omitted so a clean view has a clean URL; page comes back as a number.
URLSearchParams does the encoding that a hand-built string gets wrong the
first time a search term contains & or a space.
Brief it, then review it
Add /products with its filters in the query string (q, categories,
sort, page). Parse them with fromQuery on load and on popstate; write
them with toQuery through the router, never location.href. Omit
defaults. Add a catch-all route that renders NotFound.
- Internal links use the router’s link component, never a bare
<a>. - The route table ends in a catch-all.
- Focus moves to the new view’s heading after navigation.
- Refresh and the back button reproduce the exact filtered view.
Encode it, then practise it
SKILL.md that encodes Router for a coding agent. Install it into your agent, or download it for any Agent-Skills-compatible runtime.
npx skills add grvpanchal/elegant --skill server-router
Practise it
Round-trip filter state through the URL
Serialise a filter object to a query string and parse it back, so a filtered view is shareable and the back button works.
Course contents (7 lessons)
Module 1: Routes and containers
Module 2: Rendering strategies
- SSR: HTML per request, and the hydration bill done
- SSG: render once at build time, cache it right done
- App shell: cache the frame, stream the data done
Module 3: The network edge