FrontendPro

89Implement a basic client-side router using the History API

mediumAbout 45 minutesCodingroutinghistory-apispa

Problem

Implement a small single-page-app router.

1. History adapters with the same interface, { location, push(path), replace(path), back(), listen(callback) → unlisten }, where location is { pathname, search }:

  • createBrowserHistory() uses history.pushState, history.replaceState and the popstate event. Note that pushState does not fire popstate, so push and replace must notify listeners themselves.
  • createMemoryHistory(initialPath = "/") keeps entries in an array. It is used for tests and server rendering. (The editor's sandboxed preview blocks pushState, so the tests use this one.)

2. createRouter(routes, history), where routes is [{ path: "/users/:id", name }] and "*" matches anything:

  • router.match(pathname) returns { name, params } for the first matching route; :segments become params (URL-decoded). Trailing slashes are ignored.
  • router.current() returns the match for the current location plus query (an object from the search string).
  • router.navigate(path, { replace = false }) updates the history.
  • router.subscribe(callback) calls callback(router.current()) after every navigation, including back/forward.
  • router.handleLinkClick(event) intercepts clicks on <a href="/…"> and navigates instead of reloading. It must ignore modified clicks (Ctrl, ⌘, Shift, Alt), non-left buttons, links with target or download, external links (http…, //…, mailto:), and events already defaultPrevented.

Try it yourself

Write your solution, run it, then submit to check it against the tests.

App.jsxReact + DOM

Step-by-step

The router only talks to { location, push, replace, back, listen }. Swapping the browser implementation for a memory one makes the router testable and usable on the server.

Unlock the full solution

What's inside

  • Step-by-step
  • Approach
  • Solution
  • Complexity
  • Edge cases
  • Follow-up questions
  • Tests

Includes 2 code listings, 5 edge cases, 4 follow-up questions.

One-time payment by UPI, card or net banking. Launch price.

All 150 answersOne payment, yours forever