Skip to content

Instantly share code, notes, and snippets.

@DavidKuennen
Last active October 24, 2024 18:10
Show Gist options
  • Save DavidKuennen/443121e692175d6fc145e1efb0284ec9 to your computer and use it in GitHub Desktop.
Save DavidKuennen/443121e692175d6fc145e1efb0284ec9 to your computer and use it in GitHub Desktop.
Minimal Analytics Snippet
(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
});
@CharbelNemnom
Copy link

Thank you @jahilldev,

Yes, I understood the logic behind creating the request.

I have created the Analytic Endpoint, but still, the Firefox Private Mode browser is not working.
If I access it from a normal browser, I can see real-time data so the endpoint that I created is working.

Any help is highly appreciated.

Thanks!

@jahilldev
Copy link

jahilldev commented Sep 14, 2022

@CharbelNemnom It's difficult for me to help without knowing more context around exactly what you're doing.

Given "Firefox Private Mode" does its best to block tracking, it could be that something you're doing is triggering their logic somehow.

Anecdotally, I know people have achieved this by using the custom endpoint, but I haven't personally.

I'd suggest we continue this via an issue below, given this is a little off topic for this Gist.
https://github.com/jahilldev/minimal-analytics

If I have a minute, and you can provide some kind of repo outlining exactly what you're doing, I might be able to help, but can't guarantee anything, I'm afraid.

My initial suggestions:

  • Attempt to find out exactly what conditions Firefox are using to constitute tracking
  • Debug where in the code the request is being blocked, if at all
  • Experiment with different endpoint names, given this is likely the primary condition they're using, in conjunction with known tracking domain names

Let me know how you get on (in a seperate issue, please!)

Thanks 👍

@CharbelNemnom
Copy link

Thank you so much @jahilldev,

I have opened an issue on your repo: https://github.com/jahilldev/minimal-analytics
So we can continue troubleshooting there.

Many Thanks!

@OMEGAYALFA
Copy link

Hola a todos, creo que lo logré. Aquí está mi publicación (con código y referencia a Gist) sobre un fragmento muy mínimo de Google Analytics 4

Gracias....

@wpsumo
Copy link

wpsumo commented Jun 24, 2023

@jahilldev Any process on inline event tracking like the onclick="ga('send', 'event', 'eventCategory', 'eventAction', 'eventLabel');"

Basically all I want is to do as you had in universal Event: ma.trackEvent('Category', 'Action', 'Label', 'Value')

How would it look for example on a link element.

<a href="https://example.com/link/">Visit</a>

Like

<a class="button" href="#" onclick="gtag('event', <action>, {
		  'event_category': <category>,
		  'event_label': <label>
		});">
	<span class="button_label">Start now
	</span>
</a>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment