I’m working on a legacy single-page application that uses AJAX to load different internal views. After recent browser updates the Browser Back Button stopped behaving as expected.
The current problem:
When the user clicks the Back button in Firefox, everything works as intended — the app restores the previous in-app view without leaving the page.
In Chrome, the first Back click correctly restores the previous in-app view but the second Back click always kicks the user out of the app and back to the login screen.
I’m already using history.pushState and listening to popstate to restore the internal content and re-push guard states when needed.
It seems like Chrome doesn’t honor the guard state or simply navigates past it.
I’ve tried:
-Unique hash fragments for every state
-Replacing the base state
-Re-pushing guard states in popstate
None of it seem to make a difference in Chrome.
function sendAction(action, content) {
// Capture current dynamic content
const section = document.querySelector('.content section.rows');
const html = section ? section.innerHTML : '';
// Push in-app navigation state
const newUrl = window.location.href.split('#')[0] + '#' + encodeURIComponent(content);
history.pushState({ html, content }, null, newUrl);
// (Ajax content loading happens here)
}
// Back button handling
window.addEventListener('popstate', function(event) {
const section = document.querySelector('.content section.rows');
if (event.state && event.state.html && section) {
// Restore previous HTML content
section.innerHTML = event.state.html;
event.preventDefault();
return;
}
// Prevent leaving the app
history.pushState({ guard: true }, null, window.location.href);
event.preventDefault();
});
// Initialize base history state
if (!history.state) {
const section = document.querySelector('.content section.rows');
history.replaceState(
{ initialized: true, html: section ? section.innerHTML : '' },
null,
window.location.href
);
}