Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Write Google Analytics Client ID to localStorage
<!--
Replace existing standard gtag.js tracking-code with this
snippet in order to store the Client ID in localStorage and use this ID when present
converted for direct code implementation from Simo Ahava´s solution for GTM; see
https://www.simoahava.com/analytics/use-localstorage-client-id-persistence-google-analytics/
for details
Client IDs will survive deletion of cookies by user or ITP 2.1
- replace UA-xxxxx-y with your own property id (2 instances)
- adjust special configuration like custom dimensions if present in existing code
- tracker is initialized with option 'anonymize_ip': true. Delete (2 instances) if not needed
- you do not need this comment or the other comments in the code below in a live source code - delete them after implementation!
NOTE: this solution only works for single-host domains like www.domain.com.
If you measure multiple subdomains like blog.domain.com, www.domain.com, app.domain.com
in a single property, localStorage is no solution!
-->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-xxxxx-y"></script>
<script>
var GA_TRACKING_ID = 'UA-xxxxx-y';
var localStorageCid = {
objectName: 'ga_client_id',
expires: 1000*60*60*24*365*2
};
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
if (window.localStorage) {
var lsCid;
var jsonObj = window.localStorage.getItem(localStorageCid.objectName) || '{}';
var obj = JSON.parse(jsonObj);
var now = new Date().getTime();
if (obj.clientId && obj.expires) {
if (now <= obj.expires) {
lsCid = obj.clientId;
}
}
//initialize - but do not send auto-hit
//add your own additional options here if present in existing code
gtag('config', GA_TRACKING_ID, { 'anonymize_ip': true, 'send_page_view': false, 'client_id': lsCid});
//pageview gets sent now with callback for storing the Client ID
gtag('event', 'page_view', {
'event_callback': function() {
var tracker_id = GA_TRACKING_ID.replace(/-/g, '_');
var tracker = window.ga.getByName('gtag_'+tracker_id);
var _lsc_clientId = tracker.get('clientId');
var _lsc_obj = JSON.stringify({
clientId: _lsc_clientId,
expires: new Date().getTime() + localStorageCid.expires
});
window.localStorage.setItem(localStorageCid.objectName, _lsc_obj);
}
});
}
else {
//add your own additional options here if present in existing code
gtag('config', GA_TRACKING_ID, { 'anonymize_ip': true });
}
</script>
<!--
Replace existing standard Universal Analytics tracking-code with this
snippet in order to store the Client ID in localStorage and use this ID when present
converted for direct code implementation from Simo Ahava´s solution for GTM; see
https://www.simoahava.com/analytics/use-localstorage-client-id-persistence-google-analytics/
for details
Client IDs will survive deletion of cookies by user or ITP 2.1
- replace UA-xxxxx-y with your own property id
- adjust special configuration like custom dimensions below if present in existing code
- you do not need this comment or the other comments in the code below in a live source code - delete them after implementation!
NOTE: this solution only works for single-host domains like www.domain.com.
If you measure multiple subdomains like blog.domain.com, www.domain.com, app.domain.com
in a single property, localStorage is no solution!
-->
<script>
var GA_TRACKING_ID = 'UA-xxxxx-y';
var localStorageCid = {
objectName: 'ga_client_id',
expires: 1000*60*60*24*365*2
};
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
if (window.localStorage) {
var lsCid;
var jsonObj = window.localStorage.getItem(localStorageCid.objectName) || '{}';
var obj = JSON.parse(jsonObj);
var now = new Date().getTime();
if (obj.clientId && obj.expires) {
if (now <= obj.expires) {
lsCid = obj.clientId;
}
}
ga('create', GA_TRACKING_ID, { 'clientId': lsCid });
ga(function(tracker) {
var _lsc_clientId = tracker.get('clientId');
var _lsc_obj = JSON.stringify({
clientId: _lsc_clientId,
expires: new Date().getTime() + localStorageCid.expires
});
window.localStorage.setItem(localStorageCid.objectName, _lsc_obj);
});
}
else {
ga('create', GA_TRACKING_ID, 'auto');
}
//Comment out if no anonymization required
ga('set', 'anonymizeIp', true);
//add additional configuration here. Example
//ga('set', 'dimension1', 'foo');
ga('send', 'pageview');
</script>
@mbaersch

This comment has been minimized.

Copy link
Owner Author

commented Mar 2, 2019

Angepasste Google Analytics Trackingcodes zur Speicherung der Client ID

ITP 2.1 geht mit der Löschung von First Party Cookies nach 7 Tagen einfach zu weit und verhindert sinnvolle Webanalyse.

Speichern der Client ID des _ga-Cookies von Google Analytics im localStorage des Browsers zum Erhalt der ID bei Löschung von Cookies durch den Benutzer oder Trackingschutz-Mechanismen wie ITP 2.1+ in Safari

Alternative Fassungen für direkt implementierten Google Analytics Trackingcode in Universal Analytics (unten) oder gtag.js (oben) Syntax der GTM-basierten Lösung von Simo Ahava.

@mbaersch

This comment has been minimized.

Copy link
Owner Author

commented Mar 2, 2019

Hinweis zur gtag.js - Lösung
gtag.js ist - Stand 03/2019 - nur eine "Hülle" für Universal Analytics. Intern arbeitet also noch immer der altbekannte Tracker. Auf der anderen Seite fehlen wichtige Konzepte für detailreiche Implementierungen wie customTasks etc. (noch) in der aktuellen Implementierung.

Die obige Lösung muss daher über den Umweg des intern genutzten "ga-Trackers" dafür sorgen, dass die bestehende Client ID (entweder vorher ausgelesen oder aus dem neuen Cookie) per Callback-Funktion in den localStorage geschrieben wird.

Das ist nicht nur eine wackelige Lösung, sondern auch darauf angewiesen, dass es den internen Universal Analytics Tracker gibt. Wenn sich gtag.js weiterentwickelt, muss dies aber in Zukunft nicht immer der Fall sein. Daher kann diese Fassung des Codes nur eine Zwischenlösung darstellen. Generell ist es nicht empfehlenswert, bei Nutzung von customTask oder anderer von gtag.js noch nicht direkt unterstützter Funktionen auf solche Provisorien zu setzen. Besser ist es in solchen Fällen, nach wie vor die Universal-Syntax zu setzen - oder gleich auf den Google Tag Manager umzustellen.

@mbaersch

This comment has been minimized.

Copy link
Owner Author

commented Sep 24, 2019

Mit ITP 2.3 hat sich faktisch jeder Ausweg über localStorage potentiell erledigt. Daher bleiben eigentlich nur noch Lösungen übrig, die (bis es auch denen an den Kragen geht) Cookies serverseitig erneuern. Siehe dazu z. B. https://gist.github.com/mbaersch/70bb1c1ee2ea4787544d1ed395de1727

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.