• SajanTech's
  • Posts
  • Track Page Metrics Easily with the Beacon API

Track Page Metrics Easily with the Beacon API

Leverage the Beacon API for guaranteed, asynchronous, and non-blocking data transmission to your server

Introduction

In today’s tutorial, we’ll explore how to seamlessly send page metrics to your web server right when a user leaves the site, ensuring you capture important data without interrupting their experience.

Prerequisite: Before we get started, make sure you have a basic understanding of JavaScript, as it’s essential for following along with this tutorial.

Why Do Metrics Matter?

Imagine you’ve built an amazing website, and you assume that every visitor will stay for at least 5 minutes. However, in reality, that may not be the case. Some users might leave after just 10 seconds, and understanding why is crucial.

That’s where metrics come in. By tracking user behavior—how often they visit, how long they stay, and when they leave you gain valuable insights. With this data, you can optimize your website to provide a better user experience and more relevant content.

Now that we’ve covered the basics of why metrics are important, let’s dive back into our main topic.

What is the Beacon API?

The Beacon API allows us to send asynchronous, non-blocking requests to a web server without expecting a response, making it ideal for scenarios like page unloads.

Why use the Beacon API? While you can send metrics with XMLHttpRequest or the fetch API, these methods don't guarantee that the request will be sent if the page is unloading. A potential fix is using synchronous requests, but that impacts performance and creates a poor user experience—using window.unload handlers, for example, was slow and unreliable.

Now, let’s explore how to send metrics using the modern, efficient Beacon API.

const metricPayload = {
    uuid: 'a51320ca-c685-4d85-9ab3-8cb6957521ee',
}
window.addEventListener('visibilitychange', (event) => {
    if(document.visibilityState === 'hidden') {
        metricPayload.metaData = {
            hasUserCurrentlyActive: false
            localDate: new Date().toLocaleDateString(),
            localTime: new Date().toLocaleTimeString()
        }
        const blob = new Blob([JSON.stringify(metricPayload)], {
            type: 'application/json'
        })
        navigator.sendBeacon('/api/metrics', blob)
    }else {
        metricPayload.metaData = {
            hasUserCurrentlyActive: true
            localDate: new Date().toLocaleDateString(),
            localTime: new Date().toLocaleTimeString()
        }
        const blob = new Blob([JSON.stringify(metricPayload)], {
            type: 'application/json'
        })
        navigator.sendBeacon('/api/metrics', blob)
    }
})

Before i break down the above piece of code. Let me explain a bit

The code uses the Beacon API to track user activity on a webpage. By listening to the visibilitychange event, we can determine when users leave or return to the page. We then send this data—along with a timestamp—using the Beacon API, which ensures the metrics are sent asynchronously and without blocking, even as the user navigates away.

This method is more reliable than traditional approaches like fetch or XMLHttpRequest for capturing data during page unloads, helping improve your web performance tracking.

Let me break the code step by step

const metricPayload = {
    uuid: 'a51320ca-c685-4d85-9ab3-8cb6957521ee',
}

This creates a constant metricPayload, which is an object containing a uuid (a unique identifier). This payload will be sent to the server whenever certain events occur.

window.addEventListener('visibilitychange', (event) => {
if (document.visibilityState === 'hidden') {
 metricPayload.metaData = {
            hasUserCurrentlyActive: false
            localDate: new Date().toLocaleDateString(),
            localTime: new Date().toLocaleTimeString()
        }
        const blob = new Blob([JSON.stringify(metricPayload)], {
            type: 'application/json'
        })
        navigator.sendBeacon('/api/metrics', blob)
   }
}
  • Here, you are attaching an event listener to the window object, listening for the visibilitychange event.

  • The visibilitychange event fires when the visibility state of the page changes. The page could either become visible or hidden (for example, when the user switches tabs or minimizes the browser).

  • Inside the event listener, you check whether the document.visibilityState is 'hidden', which means the user has left the page or minimized the browser.

  • If the page is hidden, you update the metricPayload with a metaData object that contains:

    • hasUserCurrentlyActive: false — indicating the user is no longer active.

    • localDate and localTime, which capture the current date and time when the page was hidden.

  • A Blob (binary large object) is created from the metricPayload object, which is converted into a JSON string using JSON.stringify().

  • The navigator.sendBeacon() method is then used to send this data (in the form of the blob) to the /api/metrics endpoint.

  • sendBeacon() is perfect for situations like this because it sends data asynchronously and without blocking, even when the user is leaving the page.

} else {
    metricPayload.metaData = {
        hasUserCurrentlyActive: true,
        localDate: new Date().toLocaleDateString(),
        localTime: new Date().toLocaleTimeString()
    }
    const blob = new Blob([JSON.stringify(metricPayload)], {
        type: 'application/json'
    })
    navigator.sendBeacon('/api/metrics', blob)
}

If the page becomes visible again (document.visibilityState !== 'hidden'), the same process happens, but this time the metricPayload.metaData is updated with:

  • hasUserCurrentlyActive: true — indicating the user is active again.

  • The current localDate and localTime values.

Break down summary

  • This code listens for changes in the page’s visibility (whether the user leaves or returns).

  • When the user leaves, it captures the event and sends the user activity state (active or inactive), along with the current date and time, to a server endpoint using the Beacon API.

  • The Beacon API ensures the data is sent reliably even when the user is navigating away from the page, which can be difficult with other methods like fetch or XMLHttpRequest.

This setup is a clean and efficient way to track user activity and page visibility transitions for metrics purposes!

Tip: In Chrome, where beacon requests are always shown in “Pending” status. This is expected, and it doesn’t mean your beacon is broken.

Conclusion

The Beacon API provides an efficient way to send data to the server even after the user has left the page. At Metrics, we leverage this functionality to capture and transmit final performance data, ensuring we gather crucial insights without impacting the user experience. This modern approach allows for seamless and reliable data collection, enhancing our ability to optimize web performance.

Stay Ahead with More Web Development Tips!

If you found this guide on the Beacon API helpful, make sure you don’t miss out on future insights! Subscribe to SajanTech’s newsletter for more practical tips, tutorials, and best practices on web development, performance optimization, and much more. Plus, be the first to know about new content straight to your inbox!

Join our community today and take your web development skills to the next level!

Reply

or to participate.