Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Upgrade Your Analytics Cookies to fight ITP2.1:
/* GTM : use the following code inside a customTask, hitCallback oder a cleanup tag
GA.JS : modify your existing tracking code with a customTask or hitCallback and execute the following code
GTAG.JS : modify your existing tracking code with a manual page_view event
including an event_callback (gtag.js) and execute the following code
customTask ga.js - see: https://developers.google.com/analytics/devguides/collection/analyticsjs/tasks#adding_to_a_task
hitCallback ga.js - see: https://developers.google.com/analytics/devguides/collection/analyticsjs/sending-hits#hitcallback
event_callback gtag.js - see: https://developers.google.com/analytics/devguides/collection/gtagjs/sending-data#implement_event_callback_functions
*/
//"harden" _ga cookie by calling server-side cookie renewal script to upgrade cookie
var ua = navigator.userAgent.toLowerCase();
var req = null;
//check browser - upgrade only for Safari users. This condition is optional as other browsers like Firefox wll likely follow
if ((ua.indexOf('safari') != -1) && (ua.indexOf('chrome') < 0)) {
if (window.XMLHttpRequest) req = new XMLHttpRequest();
if (req != null) {
//configured "upgrade_ga_cookie.php" script on your server required in order to work!
//see https://gist.github.com/mbaersch/70bb1c1ee2ea4787544d1ed395de1727 for details
req.open("GET", "/upgrade_ga_cookie.php", true);
req.send();
}
}
<!-- complete example for gtag.js tracking code with cookie renewal event-callback to upgrade_ga_cookie.php
(see example below) and deactvated cookie_update through ga´s tracking code. Sending the automatic pageview
is deactvated and a separate event ist used to add the callback function. Uses own cookie to renew _ga cookie
server-side every 6 days - see Simo Ahava´s example at
https://disqus.com/home/discussion/simoahava/create_a_cookie_rewrite_web_service_using_the_google_cloud_platform/
usage: replace (both!) UA-1234567890-1 with your own property id -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-1234567890-1"></script>
<script>
function getCookie(cname) {
var name = cname + "=";
var decodedCookie = decodeURIComponent(document.cookie);
var ca = decodedCookie.split(';');
for(var i = 0; i <ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-1234567890-1', {'cookie_update': false, 'anonymize_ip': true, 'send_page_view': false});
gtag('event', 'page_view', {
'event_callback': function() {
var cid = getCookie('_ga');
var req = null;
var didUpdate = (getCookie('ga_updated') === "true");
if (cid && !didUpdate) {
if (window.XMLHttpRequest) req = new XMLHttpRequest();
if (req != null) {
req.open("GET", "/upgrade_ga_cookie.php", true);
req.send();
document.cookie = 'ga_updated=true;path=/;max-age=' + 60*60*24*6;
}
}
}
});
</script>
<!-- complete example for analytics.js tracking code with cookie renewal hitCallback to upgrade_ga_cookie.php
(see example below) and deactivated cookie_update through ga´s tracking code. Uses own cookie to renew _ga cookie
server-side every 6 days - see Simo Ahava´s example at
https://disqus.com/home/discussion/simoahava/create_a_cookie_rewrite_web_service_using_the_google_cloud_platform/
usage: replace UA-1234567890-1 with your own property id -->
<script>
function getCookie(cname) {
var name = cname + "=";
var decodedCookie = decodeURIComponent(document.cookie);
var ca = decodedCookie.split(';');
for(var i = 0; i <ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
(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','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-1234567890-1', 'auto', {cookieUpdate: false});
ga('set', 'anonymizeIp', true);
ga('send', 'pageview', {
hitCallback: function() {
var cid = getCookie('_ga');
var req = null;
var didUpdate = (getCookie('ga_updated') === "true");
if (cid && !didUpdate) {
if (window.XMLHttpRequest) req = new XMLHttpRequest();
if (req != null) {
req.open("GET", "/upgrade_ga_cookie.php", true);
req.send();
document.cookie = 'ga_updated=true;path=/;max-age=' + 60*60*24*6;
}
}
}
});
</script>
@mbaersch

This comment has been minimized.

Copy link
Owner Author

commented Mar 2, 2019

Upgrade Your Analytics Cookies to fight ITP2.1
When localStorage (example code for gtag.js or ga.js) and / or setting server-side cookies directly from your CMS is no option, you might want to modify your tracking code or existing Google Tag Manager setup and call a helper script on your server in order to "upgrade" your _ga-Cookie so it can survive the 7-day-cap in Safari´s ITP 2.1.

You can use fields like hitCallback or customTask... or even call the code from callback-example.js any other time and in a completely independent script block (after tracking) if you like. As long as every page contains the call so that the cookie gets an updated exiration date tracking should not be impacted beyond the intended effect to perserve your tracking cookies. But keep in mind that using this solution (without filter for specific browsers) can result in a significant raise in requests that your server has to handle. To reduce the load, this script only calls the helper if the visitor uses Safari (see code comment regarding Firefox). But also talk to your IT guys before implementation!

Note: changing _ga to a secure HTTP cookie alone might not do the whole job - you can check https://developers.google.com/analytics/devguides/collection/analyticsjs/cookie-usage#analyticsjs for details on other cookies you might want to "upgrade" in your helper script.

@mbaersch

This comment has been minimized.

Copy link
Owner Author

commented Jun 12, 2019

As described in Simo Ahava´s blogpost about a rewrite web service the number of "renewal calls" can be reduced by stopping GA from updating the cookie every time. Remembering the last update in a separate cookie and only sending the request if neccessary can be achieved in the same way. The only difference would be that no web service gets called but the upgrade_ga_cookie.php on your own server.

I added two examples for gtag.js and analytics.js

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.