Navigation and History in JavaScript

Introduction

Browsers track where users go with the History API and location object. Single-page apps (SPAs) change URLs without full page reloads using history.pushState. This chapter covers reading URLs, programmatic navigation, and listening for back/forward buttons.

Prerequisites

location Object

javascript
// Current page URL parts (in browser console)
console.log(location.href);
console.log(location.pathname);
console.log(location.search);
console.log(location.hash);

Navigate away (full reload):

javascript
// Assigning href reloads page
// location.href = "https://example.com/docs";

Query String with URLSearchParams

javascript
// Parse ?q=node&page=2
const params = new URLSearchParams(location.search);
console.log(params.get("q"));
console.log(params.get("page"));
 
params.set("page", "3");
const nextSearch = params.toString();
console.log(`${location.pathname}?${nextSearch}`);

history.pushState — SPA Routes

Framework routers (React Router, Vue Router) wrap the same History API.

history.replaceState

Like pushState but replaces current entry—good for redirects without extra back-stack entries.

javascript
// Language and online status — not navigation but common with locale
console.log(navigator.language);
console.log(navigator.onLine);
 
window.addEventListener("online", () => console.log("back online"));
window.addEventListener("offline", () => console.log("offline"));

Geolocation is a separate permission-gated API (navigator.geolocation)—use only with user consent.

Mini Example: Hash-Based Tab Switch

Hash routing avoids server config for simple demos; path routing needs server fallback to index.html.

FAQ

pushState vs location.hash?

pushState gives clean URLs (/app/settings); hashes (#/settings) are easier for static hosting without rewrite rules.

<a target="_blank" rel="noopener noreferrer"> for external URLs.

SSR frameworks?

Server must know routes too—client-only pushState is not enough alone.

What comes next?

Web Workers.