— I tried to avoid discussing security / bot spam as you should figure it out with your own solution, what works for me may not work for you and you may already use 3rd party tools for it.
We’ve had several custom-built solutions since 2015. Over the years, iOS has repeatedly thrown us curveballs with stricter privacy blocks, but we managed to overcome them time after time. By integrating tools like Sentry, Clarity, and others, we’ve built an ultimate solution that’s adaptable, efficient, and compliant with evolving privacy standards.
User ID: The Core of the System
It all starts with the user ID. We generate one using the rand()
function on our frontend. For multi-domain setups, you can pass this ID to the language switcher. For example:
Upon a visit, we will generate an ID, unless, such was provided in our GET param.
Then, in turn, we will use the ID to create a link in our language switcher:
domain.com (links to) domain.fr?id=USERID
While this may pose a security threat, remember that it’s solely for tracking and not for authentication.
And of course that ID will be stored in a cookie/local storage/session storage.
Here’s a simple PHP function to generate a user ID:
function sidGenerator(int $length = 20): string
{
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$charactersLength = strlen($characters);
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= $characters[rand(0, $charactersLength - 1)];
}
return $randomString;
}
Storing the Customer Journey
We run a server called analytics.domain.currentTLD
. This server receives data and accepts queries from all our domains (e.g., domain.fr
points to analytics.domain.fr
).
If the id
parameter identifies the user, great! If not, the user is considered new. Apple’s privacy policies (and Google’s soon-to-follow) have rendered older tracking methods ineffective, so here’s how we adapted:
We send:
- User Agent: To analyze the device.
- Country: Provided for free by Cloudflare.
- Current Page: For journey mapping.
- Domain: For multi-site tracking.
- Ad Data: To attribute campaigns.
You’ll need two tables:
- Unique Users: For storing distinct user IDs.
- Raw Data: To log every pageview or event.
Using Clarity for User Recordings
Clarity allows you to tag recordings with a user ID. Here’s a basic integration example:
(function (c, l, a, r, i, t, y) {
c[a] = c[a] || function () {
(c[a].q = c[a].q || []).push(arguments)
};
t = l.createElement(r);
t.async = 1;
t.src = "https://www.clarity.ms/tag/" + i;
y = l.getElementsByTagName(r)[0];
y.parentNode.insertBefore(t, y);
// Add user ID here
c[a]('set', 'userId', 'USER_ID_HERE'); // Replace 'USER_ID_HERE' with your actual user ID
})(window, document, "clarity", "script", "xxxxx");
By the way, you could also add other tags and specific events directly to Clarity and then analyze based on it from the Clarity interface.
Using Sentry for Error Tracking
Sentry works similarly by tagging user actions with a user ID:
Sentry.setUser({
id: 'USER_ID_PLACEHOLDER'
});
Why This Matters for Developers and Product Managers
For Developers: This setup ensures scalable, privacy-compliant tracking. It integrates seamlessly with industry-standard tools and adapts to privacy changes from platforms like iOS and Google.
For Product Managers: This system provides actionable insights:
- Pinpoint user pain points with detailed Clarity recordings.
- Monitor journeys to identify drop-off points.
- Act swiftly on critical issues like failed payments or broken API calls with real-time Telegram alerts.
Telegram Alerts: Real-Time Issue Reporting
We set up a Telegram alert system to work alongside Sentry. It’s designed for non-error issues, such as:
- Failed payments.
- Potential security threats.
- Empty API responses.
Each alert type is sent to a dedicated Telegram channel and linked to a user ID. When something goes wrong, we can:
- Check Sentry logs.
- Review the user’s journey.
- Analyze Clarity recordings to reproduce the issue.
If the user is logged in, additional fields can track multiple IDs for more detailed data.
Conclusion
This setup bridges the gap between technical implementation and actionable insights. Whether you’re a developer looking for scalability or a product manager focused on user behavior, this system delivers results. By staying adaptable and compliant with privacy policies, it ensures your tracking tools remain effective and future-proof.
With domain-subdomain interaction as its backbone, this solution is built to withstand evolving privacy challenges while maintaining a seamless user experience.