Adopting Modern Web Analytics

   ∾   6 min read


I want to monitor the amounts of traffic on my websites, So I decided to integrate a modern Web Analytics platform.

I had previous experience with Google Analytics, it was my go-to.
However, there’s just one little problem… Google, and especially GA contradict my personal beliefs and ethics, as G is infamous for giving null F’s when it comes to respecting the user’s privacy 🥲


Fun fact:
When I want to test my central adblocker, I just type in the terminal:

ping analytics.google.com

And if its a timeout | err, I can rest assured that my adblocker is configured correctly 😌


It turn, I began to look for open source alternatives to GA, and shortly I came across this hidden gem: 💎

Umami (https://umami.is/)

Umami is a simple, fast, privacy-focused alternative to Google Analytics.

Those are exactly my preferred features when considering software; Lightweight, simple, fast, privacy-focused, and an alternative to a data-hoarding conglomerate.

I feel lucky to find Umami, it hits the spot. ‍🔥

There is even an official demo (and its meta! cool. 😎)

Obviously it will not be a suitable solution for everyone looking to implement a web analytics solution, but for my needs it is indeed a perfect fit!

I would like my web analytics platform to … :

  • Show me traffic numbers over time
  • Respect the privacy of the visitors
  • Identify my client-base (based solely on public info)

In this particular order.


Test drive

Intrigued and motivated, I tried to implement it in my websites.

First, tried to go down the mainstream road, and use the public instance.

A public instance of “X” - Is basically a server that runs some open source program “X” and is available to the general public for free (I love the amazing open source community so much ^^)

So basically the Umami project creators have spun up a public instance and its available on:

https://cloud.umami.is/

After the registration, I created a “New Website” with my testing subdomain.

I received a tracking code which looked like this:

<script async src="https://cloud.umami.is/script.js" data-website-id="{{MY_WEBSITE_UUID}}"></script>

And of course I embedded it into my testing server.

Excited to see it work, I hop back into the control panel at:
https://cloud.umami.is/
But nothing happens, no requests shown … minutes passed, still nothing.

Probably missed something smoll… Started verifying that the testing server’s deployment was successful and the tracking code snippet is indeed being executed by the clientside…

Its there, everything looks good and it should work…

Except… wait, the outbound request is being blocked … by adblocker???

Of course!!… Should have seen this one coming. 🤦🏽‍♂️

Quickly, try again after disabling all adblockers (there are several) … It works!

So I discovered that the request to fetch:

src="https://cloud.umami.is/script.js"

Is being blocked by uBlock Origin and other adblockers, probably because it has entered various blocklists.

What it means for me is that it wont work on the browsers of most of my geek visitors, because my geek visitors are in love with adblockers like kids are in love with sugar.


Feeling challenged, I began to try and find solutions, I tried to bypass adblockers!

Lol, It sounds so mischievous and sneaky, but in reality its probably what all big companies do regularly.

After few minutes I came up with two similar ideas:

  1. Use my domain to create a forward proxy to the remote Umami domain/URL.
  2. Copy the script.js from Umami to my server and serve it relatively to the target server.

Both ideas were meant to “proxify” the remote cloud.umami.is by masquerading the script’s source to my own domain (my own domain is probably not blocked by adblockers).

Seeming like a solid approach at first glance, confidently, I started implementing the first idea by going to my domain provider’s control panel and registering a “Stealth Forwarding” for some random subdomain.

How a “Stealth” forwarding differs from “regular” forwarding you ask?
It appears to differ from regular “Redirect Forwarding” in a way that the regular simply returns a HTTP status code 301 or 302 to the destination, while the “Stealth” variant is actually responding from my subdomain, while serving the destination’s content (probably by making a masqueraded request to the destination)

So after configuring the stealth forward I changed the tracking code to load the script.js from my newly configured subdomain, now my tracking code looked like this:

<script async src="https://umami-test.example.my-domain/script.js" data-website-id="{{MY_WEBSITE_UUID}}"></script>

Again, with my optimistic mindset, I perform another test, and … still blocked?? how?!

Ah, I see what’s happening here 🤦🏽‍♂️

The request to fetch script.js was successful, but after collecting some data, the script is performing a POST request to the actual analytics server, which is on the domain:
analytics.eu.umami.is

Which is obviously also blocked by my adblockers, who would’ve expected that? 🤣

So all those ideas, implementations, hacky workarounds.. just to get nowhere? oof 🫤


Devastated with my inability to proceed forward with the plan,

I decided to gracefully “sleep on it”.

Sponge-bob meme: 4 to 6 weeks later


Note:
Honestly, I don’t exactly remember why I haven’t continued by configuring a proxy from my analytics subdomain to analytics.eu.umami.is for the POST request as well.

Retrospectively, it seems like the natural thing to do, after already going through the hassle of setting up the forwarding.

Maybe I tried but could not find a comfortable and maintainable setup in reasonable time. 🤷🏽‍♂️


Note about myself:
I really enjoy self-hosting, I host a bunch of stuff on my makeshift potato-grade home server for more than 3 years in a row now, for my personal use.

There’s a voice in my head, it constantly tells me to self-host some random open source software. 🤣 jk


Self hosting Umami

So after a few days or weeks, I returned to the project with a different mindset, this time preoccupied with the intention to self-host and “own” my own Umami instance!

After reading for like 30 minutes some blog posts about self-hosting Umami (Popular topic lol) and the official docs about self-hosting Umami on Vercel as well (https://umami.is/docs/running-on-vercel)

I began by forking the repo on GH and proceeded by spinning up an instance on my Vercel account.

At first, I had a bit of difficulty with choosing the database provider (there was Supabase, Planetscale, and at the time I’m writing this now there is also Pocketbase which is gaining popularity - I should play with it some time)

But eventually I chose to go with the integral Vercel Postgres that is “built-into” Vercel (awesome!)
It was super easy to connect to my Umami instance.

Once the DB connected, in a matter of minutes I was already enjoying my freshly-spun instance.

I instantiated a “website” for my testing subdomain, and generated a tracking code which looked like this:

<script async src="https://umami.maxcode.me/script.js" data-website-id="{{MY_WEBSITE_UUID}}"></script>

Optimistically, made a page refresh, looked at the Network tab, and… success!!!
My domain is not flagged by adblockers so it’s not being blocked.

Feeling great satisfaction, I went on to embed it across all of my subdomains.

I saw pretty results on the dashboard and thus my journey for an analytics platform was concluded.