Single-Page App (SPA)

One HTML page that swaps its content with JavaScript as you navigate, so the browser never does a full reload.

SPAclient-side navigationsingel page appnever refreshes when you clickfeels like an app not a websiteno page reloadsthe router swaps the screen instead of loading a new pageapp-like navigation

See it

Live demo coming soon

What it is

A single-page app loads one HTML document and then never leaves it. A client-side router intercepts link clicks, pushes the new URL with the History API, and swaps the view in place. The tab never does a full document load, state survives navigation, and each move usually avoids fetching a completely new document. Plenty still crosses the wire (the route's code chunk, images, fonts, the data itself), just not the whole page again. Gmail, Figma, Linear, and Spotify's web player all work this way.

Reach for it when people stay a while and carry state around: editors, dashboards, chat, anything with a persistent sidebar, audio player, or in-progress form. For content sites that people arrive at from search and leave in ninety seconds, the multi-page version is usually faster and simpler.

The cost is that you now own everything the browser used to do for free. Back and forward buttons, scroll restoration, focus moving to the new view for screen reader users, per-view document titles, and error recovery are all your code now, and all of them are quietly broken in most homegrown SPAs. Also worth separating: SPA is a navigation model, not a rendering one. You can server-render the first paint and still be an SPA afterwards.

Ask AI for it

Build this as a single-page app with React Router: one index.html, a client-side router that intercepts link clicks and updates the URL through the History API with no full reload, and a persistent shell (sidebar and header) that survives navigation. Handle the browser duties explicitly: restore scroll position on back navigation, move focus to the main heading after each route change and announce it in a live region, set document.title per route, and render a route-level error boundary plus a catch-all 404 route.

You might have meant

client side renderingroutingdynamic routehydrationstate management

Go deeper