Google tag manager problem - Firing an event early, before "container loaded" message

Viewed 570

I am trying to capture IP address, hash it and store the value in session-scoped dimension in Google Analytics

First, I am firing a custom JS tag to get user IP using this method :

  function getIP(json) {
    dataLayer.push({"event":"ipEvent","ipAddress" : json.ip});  
  }
</script>

<script type="application/javascript" src="https://api.ipify.org?format=jsonp&callback=getIP"></script>

The script creates an "ipEvent" which pulls the user IP and triggers the "hash 2 ip scrambled" event to hash the values. Everything works fine but the problem is when I need to send hashed values via Pageview which is executed on [3] Container loaded.

You can see from the screenshot that the script to get IP was executed before "[3] Container loaded" message but an actual event happened after.

Any idea how this can be done (get "ipEvent" before [3] Container loaded)

enter image description here

2 Answers

No need to fire a tag for this. Well, maybe to load the hashing code. But I would just use some simple hashing function and run it inline rather than loading it from elsewhere. Unneeded network requests should be avoided.

Move your main hashing logic to a CJS variable and return the hash instead of touching the datalayer.

Now reference your shiny CJS variable in whatever tag you wanna use it in. Or, better yet, in GA config variable. Up to you really.

As a result: everything works, but no changes to DOM and to the global JS scope.

Your JSONP request is asynchronous - you send the request and the callback is executed when the results come back.

To make sure that the result of the ip api call is pushed reliably as the first event, you would have to make a synchronous call, which ipify does IMO not support (I might be wrong here) and which you do not want, because you would need to stop execution of everything else in your GTM installation. In that case you would also have to handle timeouts somehow etc. Not a good idea (and even if you resolve it outside GTM, you do not know when the result from the API call comes back).

If you really want to make sure that the IP is available in a given tag, use a tag sequence. In that case you need to include an onHtmlSuccess call in your callback function, which signals that your setup tag has executed and subsequent tags can be triggered. From the top of my head, it should look something like this:

<script>
function getIP(json) {
    dataLayer.push({"event":"ipEvent","ipAddress" : json.ip}); 
     var gtm = window.google_tag_manager[{{Container ID}}];
    gtm.onHtmlSuccess({{HTML ID}}); 
  }
</script>

<script type="application/javascript" src="https://api.ipify.org?format=jsonp&callback=getIP"></script>

Use this as setup tag in a tag sequence for the tags that require the IP. Set the follow up tag to only fire when the setup tag was successful, and set the setup tag to fire only once per page, so that the API call is not repeated for every tag.

While this does not make your tag fire before the first event (so technically it does not answer your question) it does make sure that tags require the IP are deferred until the IP is available, which as a result is probably somewhat close to what you want.

Related