---
title: "navigator.sendBeacon"
description: "Using the Beacon API for reliable analytics data transmission during page unload. Practical notes and code examples on in JS."
url: "https://h3manth.com/scribe/navigator-sendbeacon/"
canonical_url: "https://h3manth.com/scribe/navigator-sendbeacon/"
markdown_url: "https://h3manth.com/scribe/blog/navigator-sendbeacon.md"
publishDate: "2014-05-17T00:00:00.000Z"
author: "Hemanth HM"
category: "web"
tags: ["javascript","web-api","analytics"]
word_count: 167
reading_time_minutes: 1
x_markdown_tokens: 414
content_signal: "ai-train=yes, search=yes, ai-input=yes"
---

# navigator.sendBeacon

> Using the Beacon API for reliable analytics data transmission during page unload. Practical notes and code examples on in JS.

Analytics and diagnostics code are very useful, but they always result in extra time. The Beacon API comes to our rescue!

## The Problem

The browser normally ignores asynchronous XMLHttpRequests made in an unload handler. Common workarounds:
- Use synchronous XMLHttpRequest
- Delay the unload using an image element
- Create a no-op loop for several seconds

All are poor coding patterns.

## The Solution: Beacon API

The Beacon specification defines an interface for asynchronously transferring small HTTP data from the User Agent to a web server.

```javascript
navigator.sendBeacon(url, data)
// Returns true on success, false otherwise

### Before (XMLHttpRequest)
javascript
window.addEventListener('unload', logData, false);

function logData() {
  var client = new XMLHttpRequest();
  client.open("POST", "/log", false); // sync xhr
  client.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");
  client.send(analyticsData);
}

### After (Beacon API)
javascript
window.addEventListener('unload', logData, false);

function logData() {
  navigator.sendBeacon("/log", analyticsData);
}
```

## What People Say

> "It's like UDP over TCP but for webpages." — @FakeAlexRussell

> "A 'fire-and-forget' XMLHttpRequest replacement for faster page unloads (& next page loads)" — @richtibbett
