patternjavascriptModerate
Beacon API: Fire-and-Forget Analytics on Page Unload
Viewed 0 times
beacon apisendbeaconanalyticsbeforeunloadunloadpage exit
Problem
Sending analytics events in
beforeunload or unload handlers with fetch or XHR fails silently because the browser cancels pending requests when the page is being destroyed.Solution
Use
navigator.sendBeacon() which queues data to be sent after the page unloads. The browser guarantees delivery even if the page closes.// In a beforeunload or visibilitychange handler
function trackPageExit(data) {
const payload = JSON.stringify(data);
const blob = new Blob([payload], { type: 'application/json' });
// Returns true if queued successfully
const queued = navigator.sendBeacon('/analytics/exit', blob);
if (!queued) {
// Fallback: synchronous XHR (last resort, bad for performance)
const xhr = new XMLHttpRequest();
xhr.open('POST', '/analytics/exit', false); // synchronous!
xhr.send(payload);
}
}
// Better: use visibilitychange instead of beforeunload
document.addEventListener('visibilitychange', () => {
if (document.visibilityState === 'hidden') trackPageExit(metrics);
});Why
beforeunload synchronous XHR blocks page unload (bad UX). fetch requests get cancelled. Beacon sends a POST asynchronously after the page closes with no impact on navigation performance.Gotchas
- Beacon is limited to 64KB payload per call.
- Beacon always uses POST — you cannot use GET.
visibilitychangefires more reliably thanbeforeunloadon mobile (app switching).- The server will not receive a response — beacon is fire-and-forget from the client's perspective.
Revisions (0)
No revisions yet.