SPA Routing from Scratch: Why the Hash Fragment Powers Every Single-Page App
Understanding the hash-based mechanism strips away the magic from libraries like React Router and Vue Router. When a developer knows that a `<Link>` is just an `<a>` tag with a `#` and a `hashchange` listener, debugging routing bugs and evaluating framework choices becomes a matter of engineering rather than faith.
Traditional multi-page websites reload the entire DOM on every navigation, causing a visible white flash. Single-page applications eliminate this by loading a shell once and swapping content dynamically inside a mount point. The mechanism that makes this possible is the URL hash fragment—the part after the `#` symbol—which can be changed freely without triggering an HTTP request. A hand-written HashRouter class demonstrates the core logic: a routing table stored as a plain JavaScript object, a `hashchange` event listener, and a `load` method that matches the current hash to a callback and updates the DOM. The `bind(this)` pattern is essential to keep the event handler's context pointing to the router instance rather than the `window` object. This same pattern underpins every major front-end routing library, including React Router.
The creative leap of SPA routing is repurposing a browser feature designed for in-page anchor navigation to simulate full page transitions. The browser thinks it is scrolling to a bookmark, but the application treats it as a route change.
Frameworks add considerable weight to a concept that can be implemented in roughly 30 lines of vanilla JavaScript. The hand-written version exposes how thin the abstraction really is, which makes framework overhead easier to quantify.
The `bind(this)` problem in event handlers is a recurring source of bugs that persists even in modern frameworks under the hood; seeing it in a minimal router makes the pattern recognizable across codebases.