Google Tag Manager: Using eventCallback with multiple containers

Viewed 287

We are currently experimenting with Google Tag Manager. Beside couple of small pixels we want to include Google Analytics 4.

According to the documentation we need to include the tag "Google Analytics: GA4 Configuration" which inserts gtag.js into the page. This means that we have two containers on a single page.

We have multiple events that are fired on click of a button. After the events are fired we want to navigate the user to a different page. To ensure that all tags are fired before we navigate to a different page we use the provided eventCallback method.

dataLayer.push({
    event: 'add_to_cart',
    ...
    eventCallback: function(containerId, eventInformation) {
        ...
    },
});

However, due to the fact that we have two containers embedded the eventCallback is fired twice (one time for each container).

How can we know/guarantee that all containers finished firing? So far I've seen that people suggest to check if a specific container is finished (https://support.google.com/optimize/thread/3463880/optimize-firing-multiple-pageviews-and-eventcallbacks-when-implemented-through-tag-manager?hl=en) but that doesn't look like a feasible solution to me, because the order in which the containers finished is not guaranteed.

An alternative approach would be to count the number of containers that have already fired, but that would require to hardcode the number of available containers.

To me it seems like there must be a better solution than the approve described approaches. Does anybody have experience with it? Are there any best practices?

1 Answers

For me all events in the page were already built for GTM, and GTM Handels triggering events to GA4 & UA. So I only needed the callback for GTM. Before adding the blow solution to my code the callbacks were firing twice causing multiple issues. My solution:

const buildGtmCallback = (callback) => {
 //GA4 is also a container, so need to fire callbacks only once, for GTM container
 //GA4 containerId starts with G-
 return (containerId) => {
    if (containerId.startsWith("GTM-") && typeof callback === "function") {
        callback();
    }
 }
}

And then whatever you wish to be fired only once:

window.dataLayer.push({
     'event': 'add_expense',
     'eventCallback': buildGtmCallback(() => {
                         console.log('Call me only once');
                      })
     });

And as I mentioned - the code fires event to GTM, which (if needed) will fire those to GA4, UA or whatever is defined. According to google docs “eventCallback” is called after all of those were called so I found this solution to work without issues

Related