:: krowemoh

Wednesday | 15 OCT 2025
Posts Links Other About Now

previous
next

Detecting Browser Page Changes

2025-10-04

There isn't an easy way to detect if the web page is being refreshed, closed or if a link has been pressed. I have an onbeforeunload function that I want to run only when the browser is closed but currently it fires on using F5 or following a link on the same website.

This seems to be the intended behavior and there isn't a variable that we can query to get what the real event that's happening is.

We can solve this by adding some extra javascript to detect the various things and have a global variable that we update. This way in the onbeforeunload we can check the global variable to see what event is happening.

const EXIT = { CLOSE: "CLOSE", NAV: "NAVIGTION", REFRESH: "REFRESH", LIVERELOAD: "LIVE-RELOAD" };

let browserExitStatus = EXIT.CLOSE;

document.addEventListener("DOMContentLoaded", () => {
    document.addEventListener("click", e => {
        if (e.target.closest("a")) browserExitStatus = EXIT.NAV;
    });
    
    window.addEventListener('keydown', (e) => {
        if (e.key === 'F5' || (e.key === "r" && e.ctrlKey) || (e.key === "R" && e.ctrlKey && e.shiftKey)) {
            browserExitStatus = EXIT.REFRESH;
        }
    });
    
    window.onbeforeunload = () => {
        if (browserExitStatus === EXIT.CLOSE) {
            // Send a message to the server
        }
    };
});

The first thing we set up is the EXIT enum. It has the different types of browser events that we can set. The LIVERELOAD status is specifically for the livereload node package. This package uses window.location.reload to refresh the page and so I needed to set the status inside that package as well.

The next interesting part is the event listeners. We add an event listener to every a tag and if it is being clicked, we then set the status to EXIT.NAV. This means that the browser is currently navigating.

The next section is to add an event to monitor keypresses. We only care about F5 and other refresh shortcuts. This way we can see if the page is being refreshed.

Outside of these events, the browser is most likely exiting the page.

We can then check the exit status in onbeforeunload and do something specific like sending a message to a server only when the page is being closed. We don't want to send a message if the user refreshed or is changing pages.

This works relatively well, the only thing to note is that if you do any programmatic navigation, you will need to update the browserExitStatus manually. This also doesn't handle forms or buttons, I may add these in the future if I need it.