Static Sites & Deployment

Client-Side Routing

Definition

Client-side routing moves the job of matching an address to a page out of the host and into the browser. A router library keeps a table of patterns — '/', '/posts/:id', '/settings' — each paired with a component to render. When the application starts it matches the current path against that table; when a visitor clicks an internal link it matches again and swaps the view. The address bar is kept honest through the History API, so the URLs stay real, shareable and bookmarkable rather than collapsing to a single address. This is the navigation mechanism inside a single-page application, and React Router, Vue Router and SvelteKit's router are the usual implementations. The host, meanwhile, knows nothing about any of those paths.

Why It Matters

Moving between screens without a document load is noticeably faster — commonly 30 to 80 milliseconds to swap a view against 300 or more for a fresh page — and state survives the move, so a half-filled form or an open sidebar is not thrown away. The arrangement does split knowledge between two places that have to agree. The browser believes '/posts/17' is a page; the host has never heard of it. That mismatch is harmless right up until a request reaches the host directly, which happens on a refresh, a bookmark, a pasted link or a crawler visit, and then the host answers honestly that no such file exists. Fixing it is a hosting job, not a framework one.

How It Works

The router attaches a handler to internal links, calls preventDefault so the browser does not navigate, then calls history.pushState with the new path. Pushing state changes the address without making a request. The router re-runs its match and renders the component for that path, and it listens for popstate so the back and forward buttons re-render instead of reloading. Hash routing is the older variant, where the path lives after a hash character, as in '/#/posts/17'; that part of a URL is never sent to the host, which is why it needs no configuration and also why the addresses look awkward. For ordinary path-based routing the host needs an SPA fallback, so that a direct request for '/posts/17' returns the site's index document rather than a 404.

Real-World Example

A photographer's portfolio is built with a framework that exports static files. Each gallery gets its own path, like '/series/coastline', so clients can be sent straight to one. Published to 99helpers with the single-page app option switched on, those links work from cold: the host returns the index document, the router reads the path, and the coastline gallery renders. With the option off, the home page loads perfectly and every shared link returns a not-found error. Same build, two different outcomes, and the difference is entirely on the host's side.

Common Mistakes

  • Building paths with plain anchor tags outside the router — the browser performs a real navigation, the whole bundle reloads, and any unsaved state is lost
  • Testing only by clicking through from the home page — the paths that break are the ones nobody arrives at from inside the app
  • Switching to hash routing purely to dodge host configuration — the addresses become harder to share and the part after the hash is invisible to most analytics and to crawlers

Related Terms

Put a file online in seconds

Drop in a document, an image, a page or a whole static website and share the link — free, with no build step and no server to set up.

Host a file free →