(function (context, trackingId, options) { | |
const history = context.history; | |
const doc = document; | |
const nav = navigator || {}; | |
const storage = localStorage; | |
const encode = encodeURIComponent; | |
const pushState = history.pushState; | |
const typeException = 'exception'; | |
const generateId = () => Math.random().toString(36); | |
const getId = () => { | |
if (!storage.cid) { | |
storage.cid = generateId() | |
} | |
return storage.cid; | |
}; | |
const serialize = (obj) => { | |
var str = []; | |
for (var p in obj) { | |
if (obj.hasOwnProperty(p)) { | |
if(obj[p] !== undefined) { | |
str.push(encode(p) + "=" + encode(obj[p])); | |
} | |
} | |
} | |
return str.join("&"); | |
}; | |
const track = ( | |
type, | |
eventCategory, | |
eventAction, | |
eventLabel, | |
eventValue, | |
exceptionDescription, | |
exceptionFatal | |
) => { | |
const url = 'https://www.google-analytics.com/collect'; | |
const data = serialize({ | |
v: '1', | |
ds: 'web', | |
aip: options.anonymizeIp ? 1 : undefined, | |
tid: trackingId, | |
cid: getId(), | |
t: type || 'pageview', | |
sd: options.colorDepth && screen.colorDepth ? `${screen.colorDepth}-bits` : undefined, | |
dr: doc.referrer || undefined, | |
dt: doc.title, | |
dl: doc.location.origin + doc.location.pathname + doc.location.search, | |
ul: options.language ? (nav.language || "").toLowerCase() : undefined, | |
de: options.characterSet ? doc.characterSet : undefined, | |
sr: options.screenSize ? `${(context.screen || {}).width}x${(context.screen || {}).height}` : undefined, | |
vp: options.screenSize && context.visualViewport ? `${(context.visualViewport || {}).width}x${(context.visualViewport || {}).height}` : undefined, | |
ec: eventCategory || undefined, | |
ea: eventAction || undefined, | |
el: eventLabel || undefined, | |
ev: eventValue || undefined, | |
exd: exceptionDescription || undefined, | |
exf: typeof exceptionFatal !== 'undefined' && !!exceptionFatal === false ? 0 : undefined, | |
}); | |
if(nav.sendBeacon) { | |
nav.sendBeacon(url, data) | |
} else { | |
var xhr = new XMLHttpRequest(); | |
xhr.open("POST", url, true); | |
xhr.send(data); | |
} | |
}; | |
const trackEvent = (category, action, label, value) => track('event', category, action, label, value); | |
const trackException = (description, fatal) => track(typeException, null, null, null, null, description, fatal); | |
history.pushState = function (state) { | |
if (typeof history.onpushstate == "function") { | |
history.onpushstate({ state: state }); | |
} | |
setTimeout(track, options.delay || 10); | |
return pushState.apply(history, arguments); | |
} | |
track(); | |
context.ma = { | |
trackEvent, | |
trackException | |
} | |
})(window, "XX-XXXXXXXXX-X", { | |
anonymizeIp: true, | |
colorDepth: true, | |
characterSet: true, | |
screenSize: true, | |
language: true | |
}); |
A better minimal analytics for GA4 https://github.com/jahilldev/minimal-analytics
A better minimal analytics for GA4 https://github.com/jahilldev/minimal-analytics
It's a different approach. More options to choose from is better for users, but leave the interpretation of which one is better to people who will be using it.
A better minimal analytics for GA4 https://github.com/jahilldev/minimal-analytics
It's a different approach. More options to choose from is better for users, but leave the interpretation of which one is better to people who will be using it.
I am using it, and in my opinion, it is better. So, I don't know what your problem is.
I am using it, and in my opinion, it is better. So, I don't know what your problem is.
The only problem is the one that you creating. I appreciate that @jahilldev found a way to extend the functionality of my initial work to give users what they may need. You are the opposite. You are the first to complain about somebody's work and the valuable time that they put into it but you are the last person to offer any advice or even pointing into solution how to make it better.
The script that I come up with taught me a lot, especially since I am not a developer in that matter so that was all new for me and I appreciate that I made something useful and learn a lot. With @jahilldev implementation, we will be able to extend it and give users some alternatives that are hard to find. I will be looking forward to seeing with the @jahilldev approach how I can extend my way or achieve it.
A simple word thank you is enough and motivates you to work forward, but your kind of attitude does the opposite.
So thank you @someguy9 @wkingnet for appreciating my work and thank @jahilldev for your time to extend the functionality.
The top appreciation goes to @DavidKuennen who initiate it and make it popular, thanks to which we can work further with GA4, and @thyngster who provided Google Analytics 4 Measurement Protocol CheatSheet that allowed understanding some of the functionality.
Thank you @idarek!