Skip to content

Instantly share code, notes, and snippets.

@austinginder
Last active January 19, 2021 15:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save austinginder/50c244e64c701e1a5a1ecd8f3719273f to your computer and use it in GitHub Desktop.
Save austinginder/50c244e64c701e1a5a1ecd8f3719273f to your computer and use it in GitHub Desktop.
Rewritten tracker.js for Fathom Lite
/*
Rewritten tracker.js template for self hosted Fathom with bundled trackerUrl details.
Use this as a template and included directly with each website you plan on tracking.
Add the following script tag to embed.
<script src="/wp-content/mu-plugins/tracker.js" data-site="ABCDEFG" defer></script>
See minified version here: https://gist.github.com/austinginder/b7690cdeca1a109d9edf58f07ea1f146
*/
window.fathom_lite=function(){
var config = {
'siteId': ''
'trackerUrl': "/your-tracker-domain.tld/collect",
}
// Fetch data site if defined
config.siteId = document.currentScript.getAttribute("data-site") || config.siteId
// convert object to query string
function stringifyObject(obj) {
var keys = Object.keys(obj);
return '?' +
keys.map(function(k) {
return encodeURIComponent(k) + '=' + encodeURIComponent(obj[k]);
}).join('&');
}
function randomString(n) {
var s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
return Array(n).join().split(',').map(() => s.charAt(Math.floor(Math.random() * s.length))).join('');
}
function getCookie(name) {
var cookies = document.cookie ? document.cookie.split('; ') : [];
for (var i = 0; i < cookies.length; i++) {
var parts = cookies[i].split('=');
if (decodeURIComponent(parts[0]) !== name) {
continue;
}
var cookie = parts.slice(1).join('=');
return decodeURIComponent(cookie);
}
return '';
}
function setCookie(name, data, args) {
name = encodeURIComponent(name);
data = encodeURIComponent(String(data));
var str = name + '=' + data;
if(args.path) {
str += ';path=' + args.path;
}
if (args.expires) {
str += ';expires='+args.expires.toUTCString();
}
document.cookie = str;
}
function newVisitorData() {
return {
isNewVisitor: true,
isNewSession: true,
pagesViewed: [],
previousPageviewId: '',
lastSeen: +new Date(),
}
}
function getData () {
let thirtyMinsAgo = new Date();
thirtyMinsAgo.setMinutes(thirtyMinsAgo.getMinutes() - 30);
let data = getCookie('_fathom_lite');
if(! data) {
return newVisitorData();
}
try{
data = JSON.parse(data);
} catch(e) {
console.error(e);
return newVisitorData();
}
if(data.lastSeen < (+thirtyMinsAgo)) {
data.isNewSession = true;
}
return data;
}
return (
setTimeout(function () {
window.fathom_lite.trackPageview();
}),
{
trackPageview: function ( vars ) {
vars = vars || {};
// Respect "Do Not Track" requests
if('doNotTrack' in navigator && navigator.doNotTrack === "1") {
return;
}
// ignore prerendered pages
if( 'visibilityState' in document && document.visibilityState === 'prerender' ) {
return;
}
// if <body> did not load yet, try again at dom ready event
if( document.body === null ) {
document.addEventListener("DOMContentLoaded", () => {
trackPageview(vars);
})
return;
}
// parse request, use canonical if there is one
let req = window.location;
// do not track if not served over HTTP or HTTPS (eg from local filesystem)
if(req.host === '') {
return;
}
// find canonical URL
let canonical = document.querySelector('link[rel="canonical"][href]');
if(canonical) {
let a = document.createElement('a');
a.href = canonical.href;
// use parsed canonical as location object
req = a;
}
let path = vars.path || ( req.pathname + req.search );
if (!path) {
path = '/';
}
// determine hostname
let hostname = vars.hostname || ( req.protocol + "//" + req.hostname );
// only set referrer if not internal
let referrer = vars.referrer || '';
if (document.referrer.indexOf(hostname) < 0) {
referrer = document.referrer;
}
var data = getData();
var d = {
id: randomString(20),
pid: data.previousPageviewId || '',
p: path,
h: hostname,
r: referrer,
u: data.pagesViewed.indexOf(path) == -1 ? 1 : 0,
nv: data.isNewVisitor ? 1 : 0,
ns: data.isNewSession ? 1 : 0,
sid: config.siteId
};
var url = config.trackerUrl
var img = document.createElement('img');
img.setAttribute('alt', '');
img.setAttribute('aria-hidden', 'true');
img.src = url + stringifyObject(d);
img.addEventListener('load', function () {
var now = new Date();
var midnight = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 24, 0, 0); // update data in cookie
if (data.pagesViewed.indexOf(path) == -1) {
data.pagesViewed.push(path);
}
data.previousPageviewId = d.id;
data.isNewVisitor = false;
data.isNewSession = false;
data.lastSeen = +new Date();
setCookie('_fathom_lite', JSON.stringify(data), { expires: midnight, path: '/' });
// remove tracking img from DOM
document.body.removeChild(img)
})
// add to DOM to fire request
document.body.appendChild(img);
},
})
}();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment