JavaScript Navigator sendBeacon() Method

Beginner
5 min read
Updated: Nov 2026
3 examples
Method

Definition

navigator.sendBeacon(url, data) queues a small HTTP POST to a server — usually analytics — and sends it asynchronously without blocking page unload or the next navigation.

Pass the required arguments shown below. Check return values and browser support before you rely on the result.

Syntax

Call navigator.sendBeacon. Start with this line.

JavaScript
navigator.sendBeacon(url, data?)
CallWhat it does
navigator.sendBeacon(url, data?)Primary signature.
navigator.sendBeacon(...)Call with the arguments your case needs.

Built into the browser. Call sendBeacon(...) on a Navigator — no import required.

Library declarations
JavaScript
navigator.sendBeacon(url, data?)

Parameters

ParameterDescription
urlRequired. Relative or absolute endpoint that accepts POST
dataOptional. Body to send (string, Blob, FormData, …)

Return Value

Return ValueDescription
*true if queued; false if not

JavaScript Examples

Example 1 — Queue a Beacon

Send a small string payload and check whether it was queued.

JavaScript
if (typeof navigator.sendBeacon !== "function") {
  console.log("sendBeacon unavailable");
} else {
  const ok = navigator.sendBeacon("/log", "session=demo");
  console.log(ok); // true if queued
}
Try It Yourself

How It Works

  1. Detect. Older environments may lack the method.
  2. Call. First argument is the URL; second is optional body data.
  3. Queue. The browser schedules an async POST — your code does not wait.
  4. Read ok. true means queued, not “server accepted.”

Example 2 — Send When the Page Hides

MDN’s recommended end-of-session pattern using visibilitychange.

JavaScript
const analyticsData = JSON.stringify({ event: "leave", t: Date.now() });

document.addEventListener("visibilitychange", () => {
  if (document.visibilityState === "hidden") {
    navigator.sendBeacon("/log", analyticsData);
  }
});
Try It Yourself

How It Works

  1. Listen. visibilitychange fires when the page’s visibility changes.
  2. Filter. Send only when state becomes "hidden".
  3. Beacon. Queues analytics without delaying navigation.
  4. Why this event. More reliable than unload / beforeunload on mobile (MDN).

Example 3 — Oversized Payload Returns false

Queued data is capped at about 64 KiB — oversize bodies are not queued.

JavaScript
const small = "x".repeat(100);
const huge = "x".repeat(70 * 1024); // ~70 KiB

console.log(navigator.sendBeacon("/log", small)); // true
console.log(navigator.sendBeacon("/log", huge));  // false
Try It Yourself

How It Works

  1. Small payload. Easy to queue → true.
  2. Over ~64 KiB. The agent refuses to queue → false.
  3. No throw. Failure is a boolean, not an exception.
  4. Need more data? Use fetch with keepalive: true (MDN).

Browser Support

Navigator.sendBeacon() is a browser Beacon API marked Baseline Widely available on MDN (since April 2018).

✓ Baseline Widely available

Navigator.sendBeacon()

Supported in Chrome, Firefox, Safari, Edge, and Opera. Ideal for small analytics POSTs that must not block navigation.

Baseline Widely available
Google Chrome All modern versions
Yes
Microsoft Edge All modern versions
Yes
Mozilla Firefox All modern versions
Yes
Apple Safari All modern versions
Yes
Opera All modern versions
Yes
Internet Explorer Not supported
No
sendBeacon() Excellent in browsers

Bottom line: Safe for modern analytics beacons. See the MDN sendBeacon() reference. Prefer visibilitychange over unload.

Frequently Asked Questions

It queues a small HTTP POST request to a URL, typically for analytics. The browser sends it asynchronously without blocking page unload or the next navigation.
No. MDN marks it Baseline Widely available (since April 2018). It is not Deprecated, Experimental, or Non-standard.
A common pattern is on visibilitychange when document.visibilityState becomes "hidden" — more reliable than unload or beforeunload, especially on mobile.
true means the user agent successfully queued the data for transfer. false means it could not queue it (for example the payload is too large).
Queued data is limited to about 64 KiB (65,536 bytes). For larger transfers, custom methods/headers, or reading the response, use fetch() with keepalive: true.
Optional data can be a string, Blob, FormData, URLSearchParams, ArrayBuffer, TypedArray, or DataView.

Next: setAppBadge()

Learn how to set an app icon badge with navigator.setAppBadge().

setAppBadge() tutorial →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

11 people found this page helpful