3 min read
Analytics and Blockers
When you’re passionate about your work and eager to know more about your audience, every detail matters—even the behind-the-scenes setup of your analytics. This is the story of how I transformed my portfolio website’s tracking setup to ensure I capture every meaningful interaction, all while staying in full control by self-hosting my analytics with Umami.
Challenge by Analytics Blockers
As a creative professional, my portfolio isn’t just a showcase of my work—it’s a window into my audience. Understanding who visits, what catches their eye, and how they engage is key to refining my craft and delivering even more personalized experiences. But like many modern websites, my analytics script was getting blocked by browsers and ad blockers. I knew I had to work around these hurdles without sacrificing data accuracy.
I had already taken the plunge to self-host Umami, a lightweight and privacy-focused analytics tool. This setup allowed me full control over my data while ensuring I was always learning more about my visitors. However, the initial integration wasn’t quite ready for prime time.
The Journey
Setting Up the Proxy
My first step was to ensure that the tracking script was loaded from a URL that wouldn’t be flagged or blocked. I decided to proxy the tracking requests through my own domain. Using Vercel’s rewrite rules, I added the following to my vercel.json
:
{ "rewrites": [ { "source": "/stats/:match*", "destination": "tracking_url/:match*" } ]}
This clever tweak redirected any request hitting /stats/
on my website to my self-hosted Umami server at tracking
. The goal was to bypass common blockers and ensure the tracking script loaded seamlessly.
Umami Integration
The integration code I was using for Umami constructs the tracking script URL by extracting only the hostname from the endpointUrl
provided. This meant that if I simply set endpointUrl
to include /stats/
, the /stats/
part would be lost during URL construction. After some tinkering, I realized I needed to adjust the settings:
endpointUrl
: I set this to"tracking_url"
. This allowed the integration to correctly extract the hostname.trackerScriptName
: By overriding this to"stats/script.js"
, I ensured that the final URL for the script becametracking_url/stats/script.js
.hostUrl
: This was set to"tracking_url/stats/"
so that all data would be sent through the proxied route.
The final configuration looked like this:
umami({ id: "umami_id", endpointUrl: "tracking_url", // Only the hostname. hostUrl: "tracking_url/stats/", // Analytics data routed through /stats. trackerScriptName: "stats/script.js" // Constructs the correct script URL.});
The Breakthrough
After deploying these changes, I watched as my portfolio began to collect data without hiccups. The tracking script was loaded flawlessly, and my self-hosted Umami instance was now receiving precise data about every page view and event. I felt a renewed sense of control and insight—a true embodiment of customer obsession.
Better Data, Better Decisions
By fine-tuning the integration, I was no longer at the mercy of third-party blockers. My analytics are now more reliable, allowing me to:
- Understand Audience Behavior: Know which projects and pieces of content captivate visitors.
- Tailor Future Work: Leverage data to guide new creative endeavors that resonate more deeply.
- Optimize the Experience: Continually adjust my portfolio to improve visitor engagement.
This journey has not only enhanced my technical setup but also reinforced my commitment to putting the customer (or in my case, the visitor) at the center of everything I do.
Final Thoughts
Integrating self-hosted analytics might seem like a small tweak, but for me, it was a turning point in how I approach my craft. Every line of code and every proxy rule was a step toward a more transparent and customer-obsessed digital experience. If you’re looking to get closer to your audience, sometimes the solution lies in these thoughtful technical details.
Happy tracking!
— Haomin