You folks may or may not be aware but Google has been migrating its analytics away from what they call 'Universal Analytics' and toward the current standard, which they call 'Google Analytics 4' or 'GA4'. At the moment, googling how to do certain things most often leads to old Universal Analytics instructions with a warning that it's deprecated and a generic, unhelpful link to some hopelessly broad/introductory GA 4 topic.

I'm trying to track when users on my site click links to external sites where they can hear and/or buy my music. I see from this documentation that one can trigger an event by calling a function, gtag():

gtag('event', '<event_name>', {
  <event_parameters>
});

It occurs to me that this event reporting function call is surely contacting the google website/api to report this event, and I am concerned that if the event is attacked to the onclick event of an <a> tag or button, that we might encounter some kind of race condition: might the browser exit the current page, terminating all pending code execution, before the API call to google gets fired?

I note that fairly deep in the rather nebulous GA 4 documentation that there is a mention of an event_callback control parameter. I'm not even sure if this parameter applies to basic GA 4 tag I'm using:

<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'G-XXXXXXXXXX');
</script>

Or whether that event_callback function control parameter only applies when using the Google Tags approach, whose markup looks a bit more complicated.

I've so far been unable to find any onclick examples in the GA4 documentation so I'm not sure how to approach this. Ideally, I'd like to track events by remote website (i.e., bandcamp versus spotify versus itunes etc.) and also by where the click happened (e.g., home page button, testimonial popup, album information page, etc.).

Does anyone have experience with GA 4? Must we take special care to wait for a gtag operation to complete when trying to fire custom events off some onclick event that takes a user to an external website?

    I managed to have a support chat with someone at Google and it was far from optimal, but I did get the dim impression that there is a possibility that an XHR request fired from an <a> tag's onclick function might fail to deliver its payload if the browser were to navigate away too quickly in response to that same click action. This dim impression wasn't so much due to any explicit statement by the google employee, but rather to the code they suggested here.

    The basic idea is that you set the onclick attribute of a link to return the result of your own function:

    <a onclick="return gtag_report_conversion('http://example.com/your-link');"
    href="http://example.com/your-link">Download now!</a>

    Where you define that function to send the event with a call to gtag() and only perform the navigation to the url in the callback function:

    function gtag_report_conversion(url) {
      var callback = function () {
        if (typeof(url) != 'undefined') {
          window.location = url;
        }
      };
      gtag('event', 'conversion', {
        'send_to': 'TAG_ID/CONVERSION_LABEL',
        'value': 1.0,
        'currency': 'USD',
        'event_callback': callback
      });
      return false;
    }

    NOTE that the gtag_report_conversion function returns false. This will prevent your <a> tag from navigating anywhere. This code is dependent on the callback running for a click on the link to actually go anywhere. If you somehow fail to load the google analytics script, e.g., by mistyping its url in your markup, that callback function will never run. This approach makes it really easy to break your <a> links.

    The google employee also acknowledged that delaying this navigation 'may affect the user experience'. I.e., the navigation might seem a bit sluggish.

    I devised a somewhat better approach. It degrades more gracefully, and your a tags should still work if the google analytics script somehow fails to load. I also let one specify one's own clickType string which is used to generate a custom event id. Assign onclick to a link like so:

    <a href="https://oldgreyhorror.bandcamp.com" onclick="return gtag_report_click(this.href, 'bandcamp');">check it out on BANDCAMP</a>

    I feel this is an improvement because you don't have to specify the url twice (it uses this.href instead) and also because you can specify a 2nd param to gtag_report_click to specify which google analytics event you want to fire. You may want different custom event ids for different links to the same location -- e.g., 'bandcamp_homepage' vs 'bandcamp_product_page' This value is prepended with 'click_' to make the event id.

    And here's the gtag_report_click function, which degrades more gracefully. Your links should still work if the google script somehow failed to load and there's no callback actions being triggered.

    // function to report link click to google
    function gtag_report_click(url, clickType) {
        if (!url || !clickType) {
            console.log('Missing url or clicktype. Just returning true');
            return true;
        }
        // I'm not sure this is entirely correct, but it seems to work
        if (!window.google_tag_data) {
            console.log('google_tag_data empty. gtag.js probably not loaded. returning true');
            return true;
        }
        // this fn performs the delayed navigation after gtag finishes reporting event to google
        var callback = function () {
            window.location = url;
        };
    
        // define custom event id, alphanums and underscores only
        // this sends the event report to google and specifies our callback fn on completion
        let clickId = 'click_' + clickType;
        gtag('event', clickId, {
            'event_callback': callback
        });
    
        // this prevents the <a> link from navigating
        return false;
    }

    If anyone can think of a better way to detect if the google analytics script has been properly loaded, I'd appreciate hearing about it. If the google analytics script isn't loaded, that all-important callback will never be invoked, and your link will be broken.

    I'd also be curious if anybody knows whether this delayed navigation is even necessary. I mean, it seems strictly necessary in some academic sense to make sure the click event is successfully delivered to google every time, but I wonder if it's necessary in practice. Like, does google get the click event 90% of the time without the delayed navigation? That might be good enough, the code would be simpler, and we wouldn't introduce this possibly sluggish user experience.

      Write a Reply...