Skip to the content.

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 of Link, routerLink or <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 exact rendered 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.
  1. Internal links use the router’s link component, never a bare <a>.
  2. The route table ends in a catch-all.
  3. Focus moves to the new view’s heading after navigation.
  4. Refresh and the back button reproduce the exact filtered view.

Encode it, then practise it

Agent Skill: server-router The 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
Download server-router SKILL.md

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.

coding medium server 25 min Solved

Course contents (7 lessons)

Module 1: Routes and containers

  1. Containers: where data meets the UI done
  2. Router: the URL is state too done

Module 2: Rendering strategies

  1. SSR: HTML per request, and the hydration bill done
  2. SSG: render once at build time, cache it right done
  3. App shell: cache the frame, stream the data done

Module 3: The network edge

  1. Proxy: one origin, and why CORS stops done
  2. Session: where tokens live, and what logout means done