How to Detect When Users Leave a Page and Safely Send Data
Understanding how to determine whether a user has left or hidden a web page—covering the Page Visibility API, beforeunload/unload events, navigator.sendBeacon, and pagehide/pageshow—enables developers to improve UX, pause resources, and reliably report analytics without sacrificing performance.
In modern web development, knowing whether a user is still on the current page is essential for user experience, data analysis, and system performance.
Switch to another browser tab or app (page becomes hidden but not closed).
Minimize the browser window (same as above).
Close the browser tab or the whole browser .
Navigate to a new URL in the current tab .
On mobile, switch to another app or return to the home screen .
Frontend provides several techniques and APIs to detect these scenarios.
Method 1: Page Visibility API (modern preferred)
This standard method detects whether a page is visible to the user, ideal for handling tab switches, window minimization, and similar cases.
Core concepts:
document.hidden: read‑only property that returns
truewhen the page is in the background or minimized, otherwise
false.
visibilitychangeevent: fires on the
documentobject when the value of
document.hiddenchanges.
Applicable scenarios:
Pause or play video/audio.
Stop or start animations or carousels.
Pause server polling and resume when the page becomes visible again.
Code example:
document.addEventListener('visibilitychange', () => {
if (document.hidden) {
// Page became hidden
console.log('User left the page (tab switch or minimize)');
// Pause video, animation, etc.
pauseMyVideo();
} else {
// Page became visible
console.log('User returned to the page');
// Resume playback
playMyVideo();
}
});Advantages:
Standard, reliable : W3C standard supported by all modern browsers.
Performance‑friendly : Designed to save CPU and battery.
Clear logic : Directly reflects the page’s visibility state.
Disadvantages:
It cannot distinguish a closed tab from a hidden tab; the
visibilitychangeevent may fire when the page is hidden, but the reason (switch or close) is unknown.
Method 2: beforeunload and unload events – traditional farewell
These events fire when the user is actually leaving the page (closing, refreshing, or navigating away).
1. beforeunload event
The event triggers just before the window, document, and its resources are unloaded, allowing you to ask the user for confirmation.
Core usage:
Prevent accidental loss of unsaved data; browsers typically show a confirmation dialog.
Code example:
Note: For security reasons, modern browsers do not allow custom text in the confirmation dialog; only a built‑in message is shown.
2. unload event
This event fires after the page has started unloading and is the traditional place for final cleanup.
Code example:
window.addEventListener('unload', () => {
console.log('User is closing or leaving the page');
// Warning: operations here may not complete!
// sendAnalyticsData();
});Major drawback: The
unloadevent is unreliable; browsers do not wait for asynchronous operations (e.g.,
fetchor
XMLHttpRequest) to finish, so network requests may be aborted.
Method 3: navigator.sendBeacon() – reliable data reporting
To solve the unreliability of asynchronous requests in
unload, the W3C introduced the
navigator.sendBeacon()API.
Core concept:
sendBeacon()sends a small amount of data asynchronously, and the browser guarantees it will be queued and sent even after the page starts unloading.
Applicable scenario:
Reliably send logs, analytics, or statistics when the user leaves the page.
How to use (often together with unload or pagehide ):
This approach is currently the best practice for sending data during page unload.
Method 4: pagehide and pageshow events – handling back‑forward cache (bfcache)
Modern browsers, especially on mobile, use a back‑forward cache. When a user navigates back, the page may be restored from cache without triggering
unload. The
pagehideevent fires regardless of bfcache.
Core concepts:
pagehideevent: fires when the user navigates away, whether the page is stored in bfcache or not.
event.persisted: true if the page is stored in bfcache, false otherwise.
Code example:
window.addEventListener('pagehide', (event) => {
if (event.persisted) {
console.log('Page is entering bfcache');
} else {
console.log('Page is being unloaded normally');
}
// Good time to send a beacon
navigator.sendBeacon('/log', getAnalyticsData());
}); pagehideis more reliable than
unload, especially on mobile, and is recommended for cleanup and data reporting.
Final recommendations
For visibility detection, prefer the Page Visibility API .
For data reporting on exit, use
navigator.sendBeacon()inside a
pagehidelistener for best compatibility and reliability.
Use
beforeunloadonly when necessary to prevent data loss, as it interrupts user interaction.
Avoid
unloadunless you need to run very simple synchronous code; asynchronous network requests are likely to be aborted.
By combining these modern APIs, developers can accurately detect user behavior and build smarter, more user‑friendly experiences without sacrificing performance.
JavaScript
Provides JavaScript enthusiasts with tutorials and experience sharing on web front‑end technologies, including JavaScript, Node.js, Deno, Vue.js, React, Angular, HTML5, CSS3, and more.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.