DEV Community

Cover image for How to log user activities using the Beacon Web API?
Tapas Adhikary
Tapas Adhikary

Posted on • Originally published at blog.greenroots.info

How to log user activities using the Beacon Web API?

The Beacon API is a relatively unknown, lightweight, and efficient way to log web page activities to a server. It is a JavaScript API that helps the developer to send a small amount of data such as, analytics or tracking information, debugging, or diagnostic data from the browser to the server.

In this article, we will learn about the Beacon API and use it to log some user activities to the server. Hope you enjoy knowing it.

The Beacon Web API

The Beacon API schedules an asynchronous and non-blocking request to a web server. There are a few specialties of the beacon request,

  • Beacon requests do not require a response. This is a huge difference from the regular XHR or fetch requests where the client(browser) expects a response from the server.
  • Beacon requests are guaranteed to be initiated before a page is unloaded, even when you close the browser.
  • Beacon requests complete without requiring a blocking request (XHR, for example).
  • Beacon requests use the HTTP POST method.

Some of the characteristics like, non-blocking, no expectations on the response make the beacon requests extremely useful to send data to the server when a page unloads(example, closing the browser, page navigations, etc.).

How to use the Beacon API?

The Beacon API has wide browser support. It works on most of the browsers except the older internet explorer versions.

Just to be on the safer side, we can test the browser support using this simple check,

if (navigator.sendBeacon) {
  // Initiate a beacon request
} else {
  // May be, fallback to XHR or fetch?
}
Enter fullscreen mode Exit fullscreen mode

The Navigator.sendBeacon() method sends a beacon request to the server. The method takes two arguments, the URL to the server and the data. The sendBeacon() method returns a boolean. It returns true when the request is placed correctly in the queue and a false otherwise.

if (navigator.sendBeacon) {
  navigator.sendBeacon('/log-tracking', data);
} else {
  // May be, fallback to XHR or fetch?
}
Enter fullscreen mode Exit fullscreen mode

The data argument of the sendBeacon() method is optional and it is of type of an ArrayBufferView, Blob, DOMString, or FormData. Let us use the FormData to create the data for our example.

function sendAnalytics(msg) {
  if (navigator.sendBeacon) {
    let data = new FormData();
    data.append('start', startTime);
    data.append('end', performance.now());
    data.append('msg', msg);

    navigator.sendBeacon('/log-tracking', data);
  } else {
    // May be, fallback to XHR or fetch?
  }
}
Enter fullscreen mode Exit fullscreen mode

In the above example, we are sending the start and end time that a user would have spent on the application. we are also sending a tracking msg that captures what are the activities user would have performed(like, button clicked, scrolled to a page section, etc.).

We can specify a handler for the unload and/or beforeunload events and call the sendAnalytics() method.

window.addEventListener('unload', function() {
  sendAnalytics(msg);
});
Enter fullscreen mode Exit fullscreen mode

As we are sending the data using the URL /log-tracking, the server-side code can log this information anywhere and use it for analytics purposes.

Here is a sample express server code that logs this information in the console. We can be creative enough to log it in the file system, database, etc. Please note, server is not sending back any response here.

app.post('/log-tracking', function(req, res) {
  console.log('**** Tracked. Now logging ****');

  let startTime = req.body.start;
  let endTime = req.body.end;
  let trackInfo = req.body.msg;

  let logMsg = '';
  let time = (endTime - startTime) / 1000;
  logMsg = `${time.toFixed(2)} seconds`;

  if (time > 60) {
      time = time / 60;
      logMsg = `${time.toFixed(2)} minutes`;
  }
  console.log('In Session for: ', logMsg);
  console.log('Tracking info: ', trackInfo);
});
Enter fullscreen mode Exit fullscreen mode

Demo

Here is a quick demo(12 seconds) to showcase how Beacon requests work. We have two buttons here. One button is to send an ad-hoc beacon request to the server and another one simulates the browser unload event.

As you see below, the server console logs the time spent information with a sample message. Also note, the information logs when the user closes the browser.

If we see the beacon request in the developer tool(Network tab), we will see the request as pending because the server doesn't send a response. That's why it is a better use when we send a beacon request on browser unload event.

image.png

Another note is, the beacon request is not an XHR request. You can see the All option is selected above to trace this request.

Source Code

All the source code used in this article and for the demo is in the GitHub repo mentioned below. Please feel free to fork, modify, and use. Show your support with a star(⭐) if you liked the project. You are welcome to follow 🀝 me on GitHub to stay connected.

GitHub logo atapas / tracker-beacon-api

Learn the Web Beacon API with examples. Try out this project to explore with hands-on.

πŸ”Ž Tracker - The Web Beacon API Demo

The Beacon API schedules an asynchronous and non-blocking request to a web server. There are a few specialties of the beacon request,

  • Beacon requests typically do not require a response. This is a huge difference from the regular XHR or fetch requests where the client(browser) expects a response from the server.
  • Beacon requests are guaranteed to be initiated before a page is unloaded, even when you close the browser.
  • Beacon requests run to completion without requiring a blocking request (for example XMLHttpRequest).
  • Beacon requests use the HTTP POST method.

This demo logs the time a user spent on the app with a simple message.

πŸš€ How to run?

Make sure you have node.js installed.

  • Clone the repository.
  • Change directory to the cloned project.
  • Do npm install or yarn.
  • Open a terminal(or command prompt) and, run the command node app.js.
  • Access…

Primary Use-cases

There are two primary use-cases where the Beacon API can be useful.

User activity tracking and analytics

You may want to capture and send an analytics report of your user activities and behavior. These activities may include,

  • How long a user was in the session?
  • What are the user interface controls users used?
  • Any other kind of telemetry information to capture.

We may want to use any of the analytics tools and services like Google analytics for this but, it is hard to convenience our customers especially with an enterprise application.

One more point about the analytics and user activity tracking is, you need to take the end user's consent before you enable a feature like this.

Debugging and diagnostics

Have you ever faced situations like a feature works locally(in the dev mode) but doesn't work as expected in the customer environment(production mode)? This is a typical situation where the Beacon API can be a day(or night) saver.

You can logically send these lightweight beacon requests to log useful trace path information and debug them as needed.

Data limit with Beacon API

There is a limit on the data that can be sent to the server using Beacon API. However, this limit is not uniform across all the browsers and user-agents.

As per the spec,

The user agent must restrict the maximum data size to ensure that beacon requests are able to complete quickly and in a timely manner.

Please read through the beacon API specifications from w3c.org for more information.

Summary

In Summary,

  • The Beacon API is a lightweight API to send a small amount of data from the browser to the server.
  • The beacon requests are non-blocking asynchronous requests. There is no expectation from the server to send a response for a beacon request.
  • The beacon requests are guaranteed to be initiated before a page is unloaded.
  • We can use it for user activities, behavior analysis, and production time debugging.
  • There are plenty of tools out that are doing the user activity, behavior analysis, and create logs. However, they are not viable many times due to the cost and our enterprise user's unfriendliness to these apps.
  • It is also important to know what is available natively with JavaScript to understand the basics better.

More read on the Beacon API is from here,

Hope you learned something new today and all set to give the Beacon API a try sooner. You may also like,


If it was useful to you, please Like/Share so that, it reaches others as well.

You can @ me on Twitter (@tapasadhikary) with comments, or feel free to follow.

Top comments (5)

Collapse
 
4nduril profile image
Tobias Barth

Hi, thanks for the article. I am considering sendBeacon for tracking in my current project. One question: everywhere it reads "small amount of data". What does that mean? Is there a limit? A best practice?
Regards

Collapse
 
atapas profile image
Tapas Adhikary

Hi Tobias,

This is a great question. Yes, there is a limit and it is up to the user-agents(browser vendors) to decide what would be the limit.

The spec says,

The user agent must restrict the maximum data size to ensure that beacon requests are able to complete quickly and in a timely manner.

Check out this link for more details: w3.org/TR/beacon/#sec-sendBeacon-m...

For example, with research, I had found that someone tested the limit on an older version of chrome on windows and found the limit to be, (2^16).

Please take a look.

var url = 'http://jsfiddle.net?sendbeacon';
var n = 65536; // sendBeacon limit for Chrome v40 on Windows (2^16)

// this method courtesy of http://stackoverflow.com/questions/14343844/create-a-string-of-variable-length-filled-with-a-repeated-character
var data = new Array(n+1).join('X'); // generate string of length n

if(!navigator.sendBeacon(url, data))
{
   alert('data limit reached');
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
4nduril profile image
Tobias Barth

Oh great, thank you very much. I hoped that there was a spec'd limit but this way I can check the relevant browsers.

Thread Thread
 
atapas profile image
Tapas Adhikary

Welcome, Tobias!

Collapse
 
atapas profile image
Tapas Adhikary

I have also added a small section about it in the article now.