Skip to main content

How to Detect the Browser Back Button Event in JavaScript

A common requirement in modern web applications, especially Single-Page Applications (SPAs), is to detect when a user clicks the browser's back or forward buttons. It's important to understand that you cannot directly "listen" for a click on the browser's back button itself. Instead, you listen for the event that the browser fires when the user navigates through their session history.

This guide will explain the two primary events for detecting this navigation: the modern popstate event, which works with the History API, and the classic hashchange event for older, hash-based routing.

The Core Concept: Listening to History, Not the Button

The browser's back button is part of the browser's user interface (its "chrome"), not part of your webpage's DOM. Therefore, you cannot attach a click listener to it. The correct approach is to listen for changes to the window's session history. When the user clicks "back" or "forward," the browser navigates to a different state in the history, and fires an event that your code can listen for.

The Wrong Tool: Why beforeunload is Not the Answer

You might see the beforeunload event suggested as a solution. This is incorrect for this use case.

The beforeunload event fires only when the user is about to leave the page entirely—by closing the tab, refreshing the page, or navigating to a completely different website. It does not fire for in-page history navigation (like when the URL hash changes or a popstate event occurs). Its purpose is to ask the user, "Are you sure you want to leave this page?"

The popstate event is the modern standard for handling history navigation in SPAs. It is designed to work with the History API (history.pushState() and history.replaceState()).

The logic:

  1. When you change the state of your application (e.g., loading a new view), you manually add an entry to the browser's session history using history.pushState().
  2. You then add a popstate event listener to the window object.
  3. When the user clicks the back button, the browser "pops" the previous state from the history stack, and your popstate listener is fired.

You have an application that changes its content without a full page reload, and you need to react when the user clicks the back button.

Solution:

const statusDisplay = document.getElementById('status');

// 1. When the state changes, update the UI and push a state to history
function updateState(newState) {
statusDisplay.textContent = `Current state is: ${newState.page}`;
// The first argument is the state object, the second is an unused title,
// the third is the URL to display.
history.pushState(newState, '', `#${newState.page}`);
}

// 2. Add the popstate listener to handle back/forward button clicks
window.addEventListener('popstate', (event) => {
if (event.state) {
// The state object from the history is in event.state
statusDisplay.textContent = `Navigated back to: ${event.state.page}`;
} else {
// This handles the initial page load state
statusDisplay.textContent = 'Current state is: home';
}
});

// --- Example Usage ---
// Simulate changing the state
updateState({ page: 'profile' }); // User navigates to the profile
// If the user now clicks the back button, the popstate listener will fire.

The Classic Method: The hashchange Event

Before the History API, SPAs managed their state using the URL's "hash" or "fragment" (the part after the #). The hashchange event fires whenever this part of the URL changes.

Solution: this method is simpler but is generally considered a legacy approach for full-featured SPAs.

// Listen for changes to the URL hash
window.addEventListener('hashchange', (event) => {
console.log(`The URL hash changed!`);
console.log('Old URL:', event.oldURL);
console.log('New URL:', event.newURL);

// You can get the new hash value from location.hash
const newHash = location.hash; // e.g., "#contact"
// (Update your page content based on the new hash)
});

// To test this, you can have links on your page like:
// <a href="#home">Home</a>
// <a href="#about">About</a>
note

When a user clicks one of these links and then clicks the back button, the hashchange event will fire.

Conclusion

You cannot directly detect a click on the browser's back button, but you can effectively handle the navigation it causes by listening for the correct window events.

  • For modern Single-Page Applications that use the History API (pushState), the popstate event is the recommended best practice.
  • For older applications or simpler cases that rely on URL hashes (#), the hashchange event is the correct tool.
  • Do not use beforeunload for this purpose, as it is designed for handling when a user leaves the page entirely.