files/en-us/web/api/navigator/sendbeacon/index.md
{{APIRef("HTML DOM")}}
The navigator.sendBeacon()
method {{glossary("Asynchronous", "asynchronously")}} sends an HTTP POST request containing a small amount of data to a web server.
It's intended to be used for sending analytics data to a web server, and avoids some of the problems with legacy techniques for sending analytics, such as the use of {{domxref("XMLHttpRequest","XMLHttpRequest")}}.
[!NOTE] For use cases that need the ability to send requests with methods other than
POST, or to change any request properties, or that need access to the server response, instead use thefetch()method withkeepaliveset to true.
sendBeacon(url)
sendBeacon(url, data)
url
data {{Optional_inline}}
Returns true if the
{{glossary("user agent")}} successfully queued the data for transfer.
Otherwise, it returns false.
This method is intended for analytics and diagnostics code to send data to a server.
A problem with sending analytics is that a site often wants to send analytics when the user has finished with a page: for example, when the user navigates to another page. In this situation the browser may be about to unload the page, and in that case the browser may choose not to send asynchronous {{domxref("XMLHttpRequest")}} requests.
In the past, web pages have tried to delay page unload long enough to send data. To do this they have used workarounds such as:
XMLHttpRequest call.src. Most user agents will delay the unload to load the image.All these methods block unloading the document, which slows down navigation to the next page. There's nothing the next page can do to avoid this, so the new page seems slow, even though it's the fault of the previous page.
With the sendBeacon() method, the data is transmitted asynchronously when the user
agent has an opportunity to do so, without delaying unload or the next navigation.
This means:
The data is sent as an HTTP POST request.
[!NOTE] The
navigator.sendBeacon()method has a spec-defined payload size limit of about 64 KiB. If this limit is exceeded, the request will fail. For larger data transfers, consider usingfetch()instead.
Websites often want to send analytics or diagnostics to the server when the user has finished with the page.
The most reliable way to do this is to send the data on the visibilitychange event:
document.addEventListener("visibilitychange", () => {
if (document.visibilityState === "hidden") {
navigator.sendBeacon("/log", analyticsData);
}
});
In the past, many websites have used the unload
or beforeunload events to send analytics at the end of a session.
However, this is extremely unreliable. In many situations, especially on mobile, the browser will not fire the
unload, beforeunload, or pagehide events. For example, these events will not fire in the following situation:
Additionally, the unload event is incompatible with the back/forward cache (bfcache)
implemented in modern browsers. Some browsers, such as Firefox, handle this incompatibility by excluding pages from the bfcache if they contain unload handlers,
thus hurting performance. Others, such as Safari and Chrome on Android, handle it by not firing the unload event when the user navigates to another page in the same tab.
Firefox will also exclude pages from the bfcache if they contain beforeunload handlers.
To support browsers which don't implement visibilitychange, use the pagehide event.
Like beforeunload and unload, this event is not reliably fired, especially on mobile. However, it is compatible with the bfcache.
The following example specifies a handler for the {{domxref("document.visibilitychange_event", "visibilitychange")}} event. The handler calls sendBeacon() to send analytics.
document.addEventListener("visibilitychange", () => {
if (document.visibilityState === "hidden") {
navigator.sendBeacon("/log", analyticsData);
}
});
{{Specifications}}
{{Compat}}
visibilitychange event.visibilitychange, not
beforeunload/unload.