跪拜 Guibai
← All articles
Frontend · React.js · JavaScript

How Hash Routing Fixed the Web's White-Screen Problem

By kisshyshy ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

Hash routing is the conceptual ancestor of every modern frontend router. Understanding its mechanics — particularly the `hashchange` event and the `this` binding trap that breaks event handlers — gives developers a clear mental model for debugging routing bugs in any framework.

Summary

Multi-page apps reload everything on navigation, causing a jarring white flash. Single-page apps eliminate that flash but break the URL, killing bookmarks, sharing, and the back button. Hash routing resolves this by using the fragment identifier — the part of a URL after the `#` — which the browser can change without sending a new request. A `hashchange` event listener then swaps page content in JavaScript, restoring the one-to-one mapping between URL and view without server involvement. The technique is simple enough to implement in a few dozen lines of vanilla JavaScript, and its constraints — ugly URLs, poor SEO — directly motivated the later History API that underpins modern routers like React Router and Vue Router.

Takeaways
Clicking a link in a traditional multi-page app triggers a full unload-request-parse-render cycle, producing a visible white flash.
Single-page apps avoid the flash by swapping DOM content with JavaScript, but the URL stays fixed, breaking bookmarks, sharing, and browser history.
Changing the hash portion of a URL (`#/about`) never sends a request to the server and does not reload the page.
Hash changes fire a `hashchange` event, which a router can listen for to swap views.
Hash values are never transmitted to the server in HTTP requests, so hash routing requires zero server-side configuration.
Passing `this.load` directly as an event handler rebinds `this` to `window`; `.bind(this)` permanently locks it to the router instance.
Hash paths with and without a leading slash (`#about` vs `#/about`) are distinct values and must be kept consistent between links and route registrations.
The HTML5 History API (`pushState`, `replaceState`, `popstate`) later replaced hash routing to enable clean URLs and better SEO.
Conclusions

Hash routing was not an arbitrary invention but a logical endpoint of a stepwise debugging process: prevent default navigation, notice the URL breaks, then search for a URL component that changes without triggering a request.

The `this` binding problem in event listeners is a rite-of-passage bug that persists in modern frontend frameworks; arrow functions and class properties are syntactic sugar over the same `.bind()` fix.

SEO was the primary force that pushed the industry from hash routing to the History API, not aesthetics — crawlers simply ignored fragment identifiers.

Concepts & terms
Hash (fragment identifier)
The portion of a URL following the `#` symbol. Browsers do not send it to the server and do not reload the page when it changes, but they do fire a `hashchange` event and record it in session history.
hashchange event
A browser event fired on the `window` object whenever the URL's fragment identifier changes. It is the core mechanism that lets a hash router detect navigation.
History API
An HTML5 API (`pushState`, `replaceState`, `popstate`) that allows JavaScript to modify the URL path without a page reload, enabling clean URLs and proper SEO for single-page applications.
`.bind(this)`
A JavaScript method that creates a new function with its `this` keyword permanently set to the provided value. It prevents event handlers from losing their intended context when invoked by the browser.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗