Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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
});
@sifigi4335
Copy link

sifigi4335 commented May 23, 2022

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.

You are the one who jumped into my comment when I didn't even mention your name, No? I will not entertain your butthurt feelings just coz you were stubborn to implement a feature that I needed, but that someone else picked up and acted on. I will not entertain your comments since this comment section is derailing from featuring the great work of David and his contribution to the community. Cheers!

@idarek
Copy link

idarek commented May 23, 2022

"coz you were stubborn to implement a feature that I needed"

There is no I in a team.
Requesting a feature vs trying to find how to implement it are two different things.
As mentioned - zero input and plenty of complaints on others' work.
My lack of knowledge (that I admit) of how to implement some things doesn't mean that I don't want to implement them.

Wish you best

@wpsumo
Copy link

wpsumo commented Jun 1, 2022

Haven't jumped on the GA4 train yet but how do you guys track events inline via onclick? And is this supported with minimal analytics v4? I read there were some limits on how many unique parameters and length you can create? This be a problem just all new, I assume this is more to setup the types of events it is? So if you have parameters "conversion" can I then have evenCategry + eventAction + eventLabel?

As an example I used this (page not needed as this can normally be matched with the normal page value in GA):
onclick="ga('send', 'event', 'eventCategory', 'eventAction', 'eventLabel');"

onclick="ga('send', 'event', 'WhatTypeOfCta', 'WhereCtaIs', 'CtaPath');"

So anyone with a good article or who can share how inline onclick event tracking work in new GA4 and we can use it with minimal analytics?

@jahilldev
Copy link

jahilldev commented Jun 1, 2022

@wpsumo I haven't been able to find official documentation (it must exist, somewhere..) about doing this programmatically, only via GTM, which is obviously not ideal given the "minimal" goals of this.

After profiling the official GA4 library, I've discovered there's another default event type of click, which you can use in conjunction with event params, e.g ?ep.custom_param=lorem or if it's a number, ?epn.price=5.

If you're using @minimal-analytics/ga4, and you want a custom click event, you'll need to add an event handler to the element, something like this:

import { track } from '@minimal-analytics/ga4';

const button = document.querySelector('button'); // use relevant selector

button.addEventListener('click', () => track({ type: 'click', event: { 'epn.product_id': 12345 } }));

The above assumes you're using a node build tool or environment to generate your site. There currently isn't a way to access track(); without this. Open to feature requests though...

I am in the process of implementing automatic anchor and button click tracking in @minimal-analytics/ga4, which is another "out of the box" event provided by the official GA4 library. That will trigger a click event with a series of event params when a user clicks an anchor or button element.

Hope that helps!

@wpsumo
Copy link

wpsumo commented Jun 28, 2022

@jahilldev Thanks for your answer, no not using any node environment. I run wordpress so php environment, I wish to be able to continue using inlined event similar to how I've used onclick today as I have a better structure there than track all click via class or ID.

As you say I did not find anything online or in the official documentation regarding this. Hopefully it will come before 2023 :D and then it can be added into minimal GA4 as well. For now if you know a solution or find, please share.

I'm not a fan of tracking all links external or internal. In this case I prefer to write them static in the html while they are dynamic via php. So it looks more like below in structure.

The only custom params I need to create if I prefer is "converted" but not necessary the rest is values which should be unlimited. The problem I see if trying to do it inline. But I have not spent hours into GA4 as I haven't seen this being supported in the official documentation yet... so no point to trying GA4 out for me right now, waiting for it though.

Event:
Converted/CTA (Category - Static)
Which CTA on the page (Action - dynamic php)
Where did the CTA go/slug (Label - dynamic php)

@jahilldev
Copy link

jahilldev commented Jun 28, 2022

@wpsumo One solution to this would be to add track to the window in @minimal-analytics/ga4, that way you'd be able to call the function in the same way you've been doing with Universal Analytics.

I'm not super keen about blanket window pollution, but maybe I could add a config option that would do this.

What do you think?

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