Beacon

Editor’s Draft,

More details about this document
This version:
https://w3c.github.io/beacon/
Latest published version:
https://www.w3.org/TR/beacon/
Feedback:
[email protected] with subject line “[beacon] … message topic …” (archives)
GitHub
Test Suite:
https://w3c-test.org/beacon/
Editors:
(Shopify)
(Compuware Corp.)
Former Editors:
(Google Inc.)
(Microsoft Corp.)

Abstract

This specification defines an interface that web developers can use to schedule asynchronous and non-blocking delivery of data that minimizes resource contention with other time-critical operations, while ensuring that such requests are still processed and delivered to destination.

Status of this document

This is a public copy of the editors’ draft. It is provided for discussion only and may change at any moment. Its publication here does not imply endorsement of its contents by W3C. Don’t cite this document other than as work in progress.

GitHub Issues are preferred for discussion of this specification.

This document is governed by the 18 August 2025 W3C Process Document.

1. Introduction

This section is non-normative.

Web applications often need to issue requests that report events, state updates, and analytics to one or more servers. Such requests typically do not require response processing on the client (e.g. result in 204, or 200 HTTP response codes with an empty response body), and should not compete for network and compute resources with other high priority operations such as fetching critical resources, reacting to input, running animations, and so on. However, such one-way requests (beacons), are also responsible for delivering critical application and measurement data, forcing developers to use costly methods to ensure their delivery:

The mismatch between above delivery and processing requirements leaves most developers with a tough choice and widespread adoption of blocking techniques that hurt the user experience. This specification defines an interface that web developers can use to schedule asynchronous and non-blocking delivery of data that minimizes resource contention with other time-critical operations, while ensuring that such requests are still processed and delivered to destination:

The following example shows use of the sendBeacon() method to deliver event, click, and analytics data:

<html>
<script>
  // emit non-blocking beacon to record client-side event
  function reportEvent(event) {
    var data = JSON.stringify({
      event: event,
      time: performance.now()
    });
    navigator.sendBeacon('/collector', data);
  }

  // emit non-blocking beacon with session analytics as the page
  // transitions to background state (Page Visibility API)
  document.addEventListener('visibilitychange', function() {
    if (document.visibilityState === 'hidden') {
      var sessionData = buildSessionReport();
      navigator.sendBeacon('/collector', sessionData);
    }
  });
</script>

<body>
 <a href='http://www.w3.org/' onclick='reportEvent(this)'>
 <button onclick="reportEvent('some event')">Click me</button>
</body>
</html>

Above example uses the visibilitychange event defined in [PAGE-VISIBILITY] to trigger delivery of session data. This event is the only event that is guaranteed to fire on mobile devices when the page transitions to background state (e.g. when user switches to a different application, goes to homescreen, etc), or is being unloaded. Developers should avoid relying on unload event because it will not fire whenever a page is in a background state (i.e. visibilityState equal to hidden) and the process is terminated by the mobile OS.

The requests initiated via the sendBeacon() method do not block or compete with time-critical work, may be prioritized by the user agent to improve network efficiency, and eliminate the need to use blocking operations to ensure delivery of beacon data.

What sendBeacon() does not do and is not intended to solve:

2. Beacon

2.1. sendBeacon() Method

partial interface Navigator {
    boolean sendBeacon(USVString url, optional BodyInit? data = null);
};

The sendBeacon() method transmits data provided by the data parameter to the URL provided by the url parameter:

Beacon API does not provide a response callback. The server is encouraged to omit returning a response body for such requests (e.g. respond with 204 No Content).

2.1.1. Parameters

2.1.2. url

The url parameter indicates the URL where the data is to be transmitted.

2.1.3. data

The data parameter is the BodyInit data that is to be transmitted.

2.1.4. Return Value

The sendBeacon() method returns true if the user agent is able to successfully queue the data for transfer. Otherwise it returns false.

The user agent imposes limits on the amount of data that can be sent via this API: this helps ensure that such requests are delivered successfully and with minimal impact on other user and browser activity. If the amount of data to be queued exceeds the user agent limit (as defined in HTTP-network-or-cache fetch), this method returns false; a return value of true implies the browser has queued the data for transfer. However, since the actual data transfer happens asynchronously, this method does not provide any information whether the data transfer has succeeded or not.

3. Processing Model

On calling the sendBeacon() method with url and optional data, the following steps must be run:

  1. Set base to this’s relevant settings object’s API base URL.

  2. Set origin to this’s relevant settings object’s origin.

  3. Set parsedUrl to the result of the URL parser steps with url and base. If the algorithm returns an error, or if parsedUrl’s scheme is not "http" or "https", throw a "TypeError" exception and terminate these steps.

  4. Let headerList be an empty list.
  5. Let corsMode be "no-cors".
  6. If data is not null:

    1. Set transmittedData and contentType to the result of extracting data’s byte stream with the keepalive flag set.
    2. If the amount of data that can be queued to be sent by keepalive enabled requests is exceeded by the size of transmittedData (as defined in HTTP-network-or-cache fetch), set the return value to false and terminate these steps.

      Requests initiated via the Beacon API automatically set the keepalive flag, and developers can similarly set the same flag manually when using the Fetch API. All requests with this flag set share the same in-flight quota restrictions that is enforced within the Fetch API.

    3. If contentType is not null:
      • Set corsMode to "cors".
      • If contentType value is a CORS-safelisted request-header value for the Content-Type header, set corsMode to "no-cors".
      • Append a Content-Type header with value contentType to headerList.
  7. Set the return value to true, return the sendBeacon() call, and continue to run the following steps in parallel:
    1. Let req be a new request, initialized as follows:

      method
      POST
      client
      this’s relevant settings object
      url
      parsedUrl
      header list
      headerList
      origin
      origin
      keepalive
      true
      body
      transmittedData
      mode
      corsMode
      credentials mode
      include
      initiator type
      "beacon"
    2. Fetch req.

4. Privacy and Security

This section is non-normative.

The sendBeacon() interface provides an asynchronous and non-blocking mechanism for delivery of data. This API can be used to:

The delivered data might contain potentially sensitive information, for example, data about a user’s activity on a web page, to a server. While this can have privacy implications for the user, existing methods, such as scripted form-submit, image beacons, and XHR/fetch requests provide similar capabilities, but come with various and costly performance tradeoffs: the requests can be aborted by the user agent unless the developer blocks the user agent from processing other events (e.g. by invoking a synchronous request, or spinning in an empty loop), and the user agent is unable to prioritize and coalesce such requests to optimize use of system resources.

A request initiated by sendBeacon() is subject to following properties:

As such, from the security perspective, the Beacon API is subject to same security policies as the current methods in use by developers. Similarly, from the privacy perspective, the resulting requests are initiated immediately when the API is called, or upon a page visibility change, which restricts the exposed information (e.g. user’s IP address) to existing lifecycle events accessible to the developers. However, user agents might consider alternative methods to surface such requests to provide transparency to users.

Compared to the alternatives, the sendBeacon() API does apply two restrictions: there is no callback method, and the payload size can be restricted by the user agent. Otherwise, the sendBeacon() API is not subject to any additional restrictions. The user agent ought not skip or throttle processing of sendBeacon() calls, as they can contain critical application state, events, and analytics data. Similarly, the user agent ought not disable sendBeacon() when in "private browsing" or equivalent mode, both to avoid breaking the application and to avoid leaking that the user is in such mode.

5. Acknowledgments

Thanks to Alois Reitbauer, Arvind Jain, Anne van Kesteren, Boris Zbarsky, Chase Douglas, Daniel Austin, Jatinder Mann, James Simonsen, Jason Weber, Jonas Sicking, Nick Doty, Philippe Le Hegaret, Todd Reifsteck, Tony Gentilcore, William Chan, and Yoav Weiss for their contributions to this work.

Conformance

Document conventions

Conformance requirements are expressed with a combination of descriptive assertions and RFC 2119 terminology. The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this document are to be interpreted as described in RFC 2119. However, for readability, these words do not appear in all uppercase letters in this specification.

All of the text of this specification is normative except sections explicitly marked as non-normative, examples, and notes. [RFC2119]

Examples in this specification are introduced with the words “for example” or are set apart from the normative text with class="example", like this:

This is an example of an informative example.

Informative notes begin with the word “Note” and are set apart from the normative text with class="note", like this:

Note, this is an informative note.

Conformant Algorithms

Requirements phrased in the imperative as part of algorithms (such as "strip any leading space characters" or "return false and abort these steps") are to be interpreted with the meaning of the key word ("must", "should", "may", etc) used in introducing the algorithm.

Conformance requirements phrased as algorithms or specific steps can be implemented in any manner, so long as the end result is equivalent. In particular, the algorithms defined in this specification are intended to be easy to understand and are not intended to be performant. Implementers are encouraged to optimize.

Index

Terms defined by this specification

Terms defined by reference

References

Normative References

[FETCH]
Anne van Kesteren. Fetch Standard. Living Standard. URL: https://fetch.spec.whatwg.org/
[HTML]
Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
[URL]
Anne van Kesteren. URL Standard. Living Standard. URL: https://url.spec.whatwg.org/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL Standard. Living Standard. URL: https://webidl.spec.whatwg.org/

Informative References

[PAGE-VISIBILITY]
Jatinder Mann; Arvind Jain. Page Visibility (Second Edition). 29 October 2013. REC. URL: https://www.w3.org/TR/page-visibility/
[SERVICE-WORKERS]
Monica CHINTALA; Yoshisato Yanagisawa. Service Workers Nightly. URL: https://w3c.github.io/ServiceWorker/

IDL Index

partial interface Navigator {
    boolean sendBeacon(USVString url, optional BodyInit? data = null);
};

MDN

Navigator/sendBeacon

In all current engines.

Firefox31+Safari11.1+Chrome39+
Opera26+Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android42+Android WebView40+Samsung Internet4.0+Opera Mobile26+