A history-backed router (state only, because the preview can't change its URL)
pushState itself fired nothing: the renders after the clicks come from navigate. Back and Forward fired popstate with the saved state; the first entry has no state, so it's null. Use the links and the Back button yourself afterwards.
A single-page app changes the view without loading a new page: history.pushState changes the address and adds a Back-button entry, the popstate event tells you when the user goes Back or Forward, and a router maps each URL to what should be shown; hash routing is the simpler, older variant.
Change the code and press Run (Ctrl+Enter). Predict what will happen first, then break it on purpose and read what changes. Your edits are saved and match the lesson page.
Ready for more? This phase has 5 hands-on exercises with automatic checks.
Practice questions
Write the code in the editor, run it, then open the model answer to compare.
Write matchRoute(path) that returns { name: "user", id: "42" } for /users/42, { name: "home" } for /, and null otherwise.
Write a navigate(path) that skips pushing when path equals the current route and otherwise pushes and renders.
Explain it without notes
What problems does client-side routing solve in a single-page app?
What do pushState, replaceState and popstate each do? Which of them fire events?
Compare hash routing and path (History API) routing.
What does a good router do besides swapping content?
Preview
Console
Nothing logged yet.Expected console output
render /
render /about
render /contact
popstate, state = { path: '/about' }
render /about
popstate, state = null
render /
popstate, state = { path: '/about' }
render /about