JavaScript Window History
The window.history object provides access to the browser's session history. It allows you to navigate back and forward, and to manipulate the history stack using pushState() and replaceState() for modern single-page applications.
history.back() and history.forward()
history.back() navigates to the previous page in history (like clicking the browser's Back button). history.forward() navigates to the next page in history (like clicking Forward).
// Go back one page
// history.back();
// Go forward one page
// history.forward();
console.log('history.back() = browser Back button');
console.log('history.forward() = browser Forward button');
// Check history length
console.log('History entries: ' + history.length);
// Note: history.length includes the current page
console.log('A length of 1 means no previous pages');history.go()
history.go() navigates to a specific page relative to the current position. Positive numbers go forward, negative numbers go back. go(0) reloads the current page.
// Go back 2 pages
// history.go(-2);
// Go forward 1 page
// history.go(1);
// Reload current page
// history.go(0);
// history.go(); // Same as go(0)
console.log('history.go(-1) = same as back()');
console.log('history.go(1) = same as forward()');
console.log('history.go(-2) = go back 2 pages');
console.log('history.go(0) = reload current page');
console.log('history.go() = reload current page');
console.log('\nhistory.length: ' + history.length);history.pushState()
pushState() adds a new entry to the browser history stack without navigating to a new page. This is the foundation of client-side routing in single-page applications (SPAs).
// pushState(state, title, url)
// state: data associated with the history entry
// title: mostly ignored by browsers (pass empty string)
// url: the URL to show in the address bar
// history.pushState({ page: 1 }, '', '/page1');
// history.pushState({ page: 2 }, '', '/page2');
// history.pushState({ page: 3 }, '', '/page3');
console.log('pushState adds a history entry');
console.log('URL in address bar changes');
console.log('Page does NOT reload');
console.log('Back button now works with SPA routing');
// Simulating state management
const historyStack = [];
function pushState(state, url) {
historyStack.push({ state, url });
console.log('Pushed: ' + url + ' (state: ' + JSON.stringify(state) + ')');
}
pushState({ page: 'home' }, '/');
pushState({ page: 'about' }, '/about');
pushState({ page: 'contact' }, '/contact');
console.log('Stack size: ' + historyStack.length);history.replaceState()
replaceState() modifies the current history entry instead of adding a new one. The URL and state are updated, but the history length stays the same.
// replaceState(state, title, url)
// Replaces current entry instead of adding new one
// history.replaceState({ page: 'updated' }, '', '/new-url');
console.log('replaceState modifies the CURRENT entry');
console.log('Does NOT add a new entry');
console.log('history.length stays the same');
console.log('\nUse cases:');
console.log(' - Update URL after form submission');
console.log(' - Correct a URL without adding to history');
console.log(' - Store updated state for current page');
console.log('\npushState vs replaceState:');
console.log(' pushState: adds entry, length increases');
console.log(' replaceState: updates entry, length unchanged');The popstate Event
The popstate event fires when the user navigates the history (clicks Back/Forward or calls history.back()/forward()/go()). It does NOT fire for pushState() or replaceState() calls.
// Listen for back/forward navigation
// window.addEventListener('popstate', function(event) {
// console.log('Navigation occurred!');
// console.log('State: ' + JSON.stringify(event.state));
// // Update the page content based on state
// if (event.state) {
// renderPage(event.state.page);
// }
// });
// Simulating SPA routing
function handleRoute(state) {
if (!state) {
console.log('Rendering: Home (default)');
return;
}
console.log('Rendering: ' + state.page);
}
// Simulating navigation events
handleRoute({ page: 'About' });
handleRoute({ page: 'Contact' });
handleRoute(null); // Back to home
console.log('\npopstate fires on Back/Forward button clicks');
console.log('event.state contains the pushState data');| Method | Adds Entry | Page Reload | Fires popstate |
|---|---|---|---|
| pushState() | Yes | No | No |
| replaceState() | No (replaces) | No | No |
| back() | No | May reload | Yes |
| forward() | No | May reload | Yes |
| go(n) | No | May reload | Yes |