Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save razorlegacy/1a89cdfa7114eb32848439b7130ac581 to your computer and use it in GitHub Desktop.
Save razorlegacy/1a89cdfa7114eb32848439b7130ac581 to your computer and use it in GitHub Desktop.
Google Tag Manager tag to load GeoIP data into the GTM data layer. Helps with GDPR.
<script src="//js.maxmind.com/js/apis/geoip2/v2.1/geoip2.js"></script>
<script>
/*
* get geographical location data by ip address
* uses the free ipify.org services
* and the paid Maxmind GeoIP2 Precision services
*/
(function (geoip2) {
"use strict";
// mark the start of the script loading
var start = (new Date()).getTime();
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
"event": "geoip.js",
"geoip.start": start
});
triggerDOMEvent(document, "geoipjs", { "start": start });
var isGeoIPLoaded, isWindowLoaded;
function onWindowLoadAndGeoIPLoad () {
if (isGeoIPLoaded && isWindowLoaded) {
// push location data into GTM data layer
window.dataLayer.push({
"event": "geoip.window.load"
});
triggerDOMEvent(document, "geoipwindowload");
}
}
// there is a possiblity that the document completes loading before now
if (document.readyState === "complete") {
isWindowLoaded = true;
onWindowLoadAndGeoIPLoad();
} else {
window.addEventListener("load", function onWindowLoad () {
isWindowLoaded = true;
onWindowLoadAndGeoIPLoad();
});
}
// helper function to push data to data layer
function onSuccess (data, doNotSaveData) {
// push location data into GTM data layer
window.dataLayer.push({
"event": "geoip.load",
"geoip.data": data
});
triggerDOMEvent(document, "geoipload", data);
isGeoIPLoaded = true;
onWindowLoadAndGeoIPLoad();
if (!doNotSaveData) {
// store data in local storage
if (data && data.traits && data.traits.ip_address) {
var key = "maxmind.geoip2.data." + data.traits.ip_address;
localStorage.setItem(key, JSON.stringify(data));
}
}
}
// helper function to log and throw error
function onError (err) {
throw new Error(err.code + ": " + err.error);
}
// helper function to execute once we have the IP address
function onIPLoaded (ip) {
window.dataLayer.push({
"event": "geoip.ip",
"geoip.ip": ip
});
triggerDOMEvent(document, "geoipip", { "ip": ip });
// check local storage for geoip data for that IP address
var key = "maxmind.geoip2.data." + ip;
var data = localStorage.getItem(key);
if (data) {
// GeoIP data found in local storage
try {
data = JSON.parse(data);
onSuccess(data, true);
} catch (err) {
throw err;
}
} else {
// fetch GeoIP data from Maxmind
geoip2.country(onSuccess, onError);
}
}
var ip = sessionStorage.getItem("ipify.ip");
if (ip) {
// use IP address retrived from session cache
onIPLoaded(ip);
} else {
// use ipify.org to get IP address
// listen for when the IP address has been loaded by ipfiy
window.ipifyCallback = function ipifyCallback (json) {
sessionStorage.setItem("ipify.ip", json.ip);
onIPLoaded(json.ip);
};
// inject the script from ipify.org
var newNode, referenceNode;
referenceNode = document.getElementsByTagName("script")[0];
newNode = document.createElement("script");
newNode.async = true;
newNode.src = "https://api.ipify.org?format=jsonp&callback=ipifyCallback";
referenceNode.parentNode.insertBefore(newNode, referenceNode);
}
// helper function to trigger native DOM events
function triggerDOMEvent (element, type, detail, bubbles, cancelable) {
// defaults
if (!(element instanceof EventTarget)) {
throw new Error("First argument, element, must be an instance of EventTarget.");
}
bubbles = bubbles || false;
cancelable = cancelable || false;
var event;
if (CustomEvent) {
// the modern way
event = new CustomEvent(type, {
"bubbles": bubbles,
"cancelable": cancelable,
"detail": detail
});
} else {
// the old fashioned way to support Internet Explorer
event = document.createEvent("Event");
event.initEvent(type, bubbles, cancelable, detail);
}
// be nice and set the current target
event.currentTarget = element;
// target can be any Element or other EventTarget.
element.dispatchEvent(event);
}
}(window.geoip2));
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment