DEV Community

Cover image for Let's build a modern time-on-site counter for your website with timeonsite.js and JS Beacons
Saleem
Saleem

Posted on • Updated on

Let's build a modern time-on-site counter for your website with timeonsite.js and JS Beacons

Timeonsite.js can be used to measure most important metric for you website time-on-page and time-on-site. Though it can be calculated simply by finding the difference between page entry and page exit with Javascript's Date object, here we are going to use a powerful web implementation of this with the help of widely popular timeonsite.js library along with the help of sendBeacon() API for safe data persistence to DB table.

Basic HTML block

<!-- 
HTML page with "counter" div container 
-->
<html><head></head>
    <div id="counter">
    </div>
</html>
Enter fullscreen mode Exit fullscreen mode

Javascript code snippet for building timer

// On page Load...
let entryTime = new Date();

//....
//User navigates the website
// some time later....

During Page exit....
let exitTime = new Date();

let timeSpent = exitTime - entryTime;
timeSpent = (timeSpent/1000); //convert to seconds

//Display the time spent with Jquery's API in page:
$(document).ready(function(){
    $('#counter').html('You have spent ' + timeSpent + 'seconds.');
});
Enter fullscreen mode Exit fullscreen mode

That's it. We have measured user's time-on-page parameter nicely. But what about its accuracy, cross-browser compatibility and data persistence when user refreshes the page many times or opens N number of browser tabs of same website? What if user has gone to visit another shopping or social media website leaving the former webpage in open state?

Since timeSpent is a variable, it cannot control the states occurring in the webpage like inactive tab or multiple tabs opened concurrently for the same website. In this case, the accuracy of the timeSpent is lost and cannot be reliably measured. Let's take a look at the APIs exposed by timeonsite.js tracker.

But timeonsite tracker's Tos.getTimeOnPage() API exposes timeonpage data every time you call the API. And we are going to use this API to show and update our counter with timer data.

{
 TOSId: 1129620185532,
 TOSSessionKey: "14802525481391382263",
 TOSUserId: "anonymous",
 title: "Blog application — Nature & Wildlife",
 URL: "http://tos-localdata.london/home.php"
 entryTime: "2021–11–27 13:15:48.663",
 exitTime: "2021–11–27 13:17:31.663",
 timeOnPage: 103,
 timeOnSite: 103,
 timeOnPageTrackedBy: "second",
 timeOnPageByDuration: "0d 00h 01m 43s",
 timeOnSiteByDuration: "0d 00h 01m 43s",
 trackingType: "tos",
}
Enter fullscreen mode Exit fullscreen mode

Step 1

Add the tracker snippet in your HTML page header

<head>
     <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/timeonsite/1.2.1/timeonsitetracker.js"></script>
</head>
Enter fullscreen mode Exit fullscreen mode

Step 2

Add the Init code of the tracker

<script>
var config = {
    // track page by seconds. Default tracking is by milliseconds
    trackBy: 'seconds',
    callback: function(data) { /* callback denotes your data tracking is real-time */
        console.log(data);
        var endPointUrl = 'http://example.com' //Replace with your actual backend API URL http://localhost/tos
        if (data && data.trackingType) {
            if (data.trackingType == 'tos') {
                if (Tos.verifyData(data) != 'valid') {
                    console.log('Data abolished!');
                    return; 
                }
            }

            // make use of sendBeacon if this API is supported by your browser.
            if (navigator && typeof navigator.sendBeacon === 'function') {
                data.trasferredWith = 'sendBeacon';
                var blob = new Blob([JSON.stringify(data)], {type : 'application/json'});
                navigator.sendBeacon(endPointUrl, blob);
            }
        }
    }
};
var Tos;
if (TimeOnSiteTracker) {
    Tos = new TimeOnSiteTracker(config);
}
</script>
Enter fullscreen mode Exit fullscreen mode

Step 3

Show the status of your time-on-page data in webpage as well

$(document).ready(function(){
    setInterval(function () {
        $('#counter').html('You have spent ' + Tos.getTimeOnPage().timeOnPage + 'seconds.');
    }, 1000); // Update the counter every second for real-time experience.
}); 
Enter fullscreen mode Exit fullscreen mode

That's it. Watch for tracker imprint in browser terminal! We are done with accurate tracking of user's time-on-site in our website. There is a demo here if you want to see.

You will see counter like this. Customize the look.
TimeOnSite sample counter in page

Timeonsite.js will take care of everything like,

1, Inactive tabs
2, Data persistence on page refresh and reloads
3, Multiple tabs of same website (because in normal JS Date object, you will end up duplicate and wrong time-on-site data)
4, Saving data to your favorite DB table on page close. (You may use already backend visual, free backend server for saving this data in PHP/NodeJS)
5, Most importantly, unprecedented accuracy of the metrics ever captured by an analytics provider!

So, you can show how much time your users spent on your site and also you can show how much time user spent in last session as log taken from DB table.

In step 2, we used following lines,

navigator.sendBeacon(endPointUrl, blob);
Enter fullscreen mode Exit fullscreen mode

This is one of the most powerful Javascript API for making HTTP post requests like XMLHTTPRequest but it works especially for retaining and saving log data during page close.

Sample SendBeacon() Request on RequestBin site

You'll see a ping in Network console unlike XHR/HTTP requests. I'm using a sample bin that causes CORS error. In normal app, it should send back success response.

Bonus point

Timeonsite.js also exposes a Tos.startActivity() API along with Tos.endActivity(). The advantage of this API is that it can track any specific activity in a site and it's bundled with same capabilities like time-on-page parameter like inactive tab, minimize tab or multiple tabs in measuring timing accuracy. Each pageview includes a TOSSessionKey to uniquely identify each activity ActivityId(TOSId) occurring in the site. Let's take an example,

// After initializing the TimeOnSiteTracker on page load, call startActivity() as
Tos.startActivity({applicantName: 'Nazir Khan'}); // this will start tracking the activity

// .
// .
// .
// after a while,

Tos.endActivity({applicantCountry: 'Romania'});
// calling .endActivity() will give back response

Gives response as,
{
    TOSId: 585872449448,
    TOSSessionKey: "14802525481391382263",
    TOSUserId: "anonymous",
    title: "Test application - TimeOnSiteTracker",
    URL: "http://tos-localdata.london/home.php",
    activityStart: "2021-11-27 13:20:46.707",
    activityEnd: "2021-11-27 13:20:50.213",
    timeTaken:4,
    timeTakenByDuration: "0d 00h 00m 04s"
    timeTakenTrackedBy: "second",
    trackingType: "activity",
    applicantName: "Nazir Khan",
    applicantCountry: "Romania"
}
Enter fullscreen mode Exit fullscreen mode

If you liked this article, go ahead and give a star on github repository. And share your comments on how it's like to build your own time-on-site counter for your webpage.

Notes
This timeonsite.js is commercial library but it's also free for non-production sites and personal websites. So, let's use the free version hosted from CDN.js hosting website.

Top comments (0)