Double Pageview with sendQueuedEvents

I’m trying to setup Google Analytics 4 requiring consent and noticed 2 pageviews for every page hit, which also end up in Analytics.

Without sendQueuedEvents() it works and only 1 pageview ends up in Analytics.

The examples in the documentation use sendQueuedEvents(). Am I not supposed to use it? I have the issue with this directly in my markup (not using Custom HTML):

// sends 2 Pageviews to Analytics
document.addEventListener('zarazConsentAPIReady', function() {
    zaraz.consent.setAll(true);
    zaraz.consent.sendQueuedEvents();
});
// sends 1 Pageview to Analytics
document.addEventListener('zarazConsentAPIReady', function() {
    zaraz.consent.setAll(true);
});

With and without sendQueuedEvents():

Is Google Analytics 4 assigned to any of the purposes?

Yes I have it assigned to a purpose:

Got it. The zaraz.consent.sendQueuedEvents(); should only be called upon the first visit of the user - its purpose is to send pageview information to tools that have been skipped due to the user not yet expressing consent. To run it only in this scenario, please update your snippet like so:

<script>
function getCookie(name) {
  const value = `; ${document.cookie}`
  return value?.split(`; ${name}=`)[1]?.split(";")[0]
}

function handleZarazConsentAPIReady() {
  if ({{system.device.location.isEUCountry}} === 1) {
    zaraz.consent.modal = true
  } else {
    const shouldSendQueuedEvents = !getCookie("cf_consent")
    zaraz.consent.setAll(true)
    if (shouldSendQueuedEvents) {
      zaraz.consent.sendQueuedEvents()
    }
  }
}


if (zaraz.consent?.APIReady) {
  handleZarazConsentAPIReady()
} else {
  document.addEventListener("zarazConsentAPIReady", handleZarazConsentAPIReady)
}
</script>

Thanks, that fixes it.

In Analytics, this gives me 1 Pageview on an initial hit (without cookies) and 1 on subsequent hits, as expected.

In Zaraz, it adds 2 Pageviews for each initial hit and 1 on subsequent hits. So using sendQueuedEvents kind of invalidates the pageviews in Zaraz, since every initial hit of a new visitor is counted twice. However, the pageviews will be reliable in Analytics.

Perhaps sendQueuedEvents could be adjusted to internally handle the cookie check? If the zaraz object is made aware of the adjustable cookie name, that would seem possible.

That should also fix it for everyone using the old documentation example in production.

Here’s an example of an adjusted sendQueuedEvents() to handle this internally. If you adjust that in zaraz itself the documentation example can go back to what it used to be.

You’d have to expose the cookie name set in Zaraz on zaraz.consent.cookieName for it to work with any cookie name.

(function () {
    function handleZarazConsentAPIReady() {
        // I'm adjusting here because zaraz is available
        // You'd adjust the original instead so cookie is set as early as possible
        var originalSendQueuedEvents = zaraz.consent.sendQueuedEvents;
        zaraz.consent.sendQueuedEvents = (function () {
            function getCookie(name) {
                var value = '; ' + document.cookie || '';
                var parts = value.split('; ' + name + '=');
                if (parts.length === 2) {
                    return parts.pop().split(';')[0];
                }
            }

            // Add zaraz.consent.cookieName for this to work
            var shouldSendQueuedEvents = !getCookie(
                (window.zaraz && zaraz.consent && zaraz.consent.cookieName) || 'cf_consent'
            );

            return function () {
                if (shouldSendQueuedEvents) {
                    originalSendQueuedEvents();
                }
            };
        })();

        // Now we can go back to using this
        zaraz.consent.setAll(true);
        zaraz.consent.sendQueuedEvents();
    }

    if (window.zaraz && zaraz.consent && zaraz.consent.APIReady) {
        handleZarazConsentAPIReady();
    } else {
        document.addEventListener('zarazConsentAPIReady', handleZarazConsentAPIReady);
    }
})();

I’ve also made things es5 compatible, added a check on window.zaraz because I’m not using Custom HTML and insert the script before zaraz is on the window. Used an IIFE to not pollute the global scope.

It might be good to make those changes to the example in the docs as well so people can just copy paste it anywhere.

It seems there’s a bug in how pageview events are counted backend-side. We’re investigating that and will be rolling out a solution in a few days