View Issue Details

IDProjectCategoryView StatusLast Update
0005340Composrcorepublic2023-02-23 00:26
ReporterChris GrahamAssigned To 
SeverityFeature-request 
Status non-assignedResolutionopen 
Product Version 
Fixed in Version 
Summary0005340: Update Google Analytics tracking code
DescriptionOur GA event tracking code ($cms.statsEventTrack) is outdated, needs rewriting for GA4 with more bulletproofing.

Below is some code for a client that has change massively from the v10 code, but is also very divergent from the v11 code. So it needs going over carefully.
Additional Information/* Google Analytics tracking for links; particularly useful if you have no server-side stat collection */
function ga_track(ob,event_name,event_primary_parameter,event_secondary_parameter,callback)
{
    // If gtag is not working (either a bug in gtag, or browser is blocking it)
    window.setTimeout(function() {
        if (typeof callback!=='undefined') {
            callback();
        } else {
            if (ob) {
                click_link(ob);
            }
        }
    }, 1000);

    /*{+START,IF_NON_EMPTY,{$CONFIG_OPTION,google_analytics}}*/
        if (typeof event_name=='undefined') event_name='{!URL;^}';
        if (typeof event_primary_parameter=='undefined') event_primary_parameter=ob?ob.href:'{!UNKNOWN;^}';
        if (typeof event_secondary_parameter=='undefined') event_secondary_parameter=window.location.href;

        try
        {
            var ga_properties=[];
            /*{+START,LOOP,{$CONFIG_OPTION,google_analytics}\,}*/
                /*{+START,IF_NON_EMPTY,{$TRIM,{_loop_var}}}*/
                    ga_properties.push('{$TRIM;^,{_loop_var}}');
                /*{+END}*/
            /*{+END}*/

            for (var i=0;i<ga_properties.length;i++) {
                var property=ga_properties[i];
                var last_one=(i==ga_properties.length-1);
                if (property.substring(0,3)=='UA-') {
                    // LEGACY
                    var parameters={
                        'event_category': event_name,
                        'event_label': event_secondary_parameter,
                        'send_to': property
                    };
                    if (last_one) {
                        if (typeof callback!=='undefined') {
                            parameters.event_callback=callback;
                        } else {
                            if (ob) {
                                parameters.event_callback=function() {
                                    click_link(ob);
                                };
                            }
                        }
                    }

                    gtag('event',event_primary_parameter,parameters);
                } else {
                    // Assumed GA4+...

                    if (event_name=='{!URL;^}') { // Automatic in GA4
                        if (last_one) {
                            if (typeof callback!=='undefined') {
                                callback();
                                return false;
                            }
                            return null;
                        }
                        continue;
                    }

                    var parameters={
                        'primary_parameter': event_primary_parameter,
                        'secondary_parameter': event_secondary_parameter,
                        'send_to': property
                    };
                    if (last_one) {
                        if (typeof callback!=='undefined') {
                            parameters.event_callback=callback;
                        } else {
                            if (ob) {
                                parameters.event_callback=function() {
                                    click_link(ob);
                                };
                            }
                        }
                    }

                    gtag('event',event_name,parameters);
                }
            }

            if (ob || typeof callback!=='undefined') {
                return false;
            }
        }
        catch(err) {}
    /*{+END}*/
    /*{+START,IF_EMPTY,{$CONFIG_OPTION,google_analytics}}*/
        if (typeof callback!=='undefined') {
            callback();
            return false;
        }
    /*{+END}*/

    return null;
}
function ga_track_structured(ob,event_name,parameters,callback)
{
    // GA4+

    /*{+START,IF_NON_EMPTY,{$CONFIG_OPTION,google_analytics}}*/
        try
        {
            var ga_properties=[];
            /*{+START,LOOP,{$CONFIG_OPTION,google_analytics}\,}*/
                /*{+START,IF_NON_EMPTY,{$TRIM,{_loop_var}}}*/
                    var property='{$TRIM;^,{_loop_var}}';
                    if (property.substring(0,3)!='UA-') {
                        ga_properties.push(property);
                    }
                /*{+END}*/
            /*{+END}*/

            for (var i=0;i<ga_properties.length;i++) {
                var property=ga_properties[i];
                var last_one=(i==ga_properties.length-1);

                // Assumed GA4+...

                if (last_one) {
                    if (typeof callback!=='undefined') {
                        parameters.event_callback=callback;
                    } else {
                        if (ob) {
                            parameters.event_callback=function() {
                                click_link(ob);
                            };
                        }
                    }
                }

                gtag('event',event_name,parameters);
            }

            if (ob || typeof callback!=='undefined') {
                return false;
            }
        }
        catch(err) {}
    /*{+END}*/
    /*{+START,IF_EMPTY,{$CONFIG_OPTION,google_analytics}}*/
        if (typeof callback!=='undefined') {
            callback();
            return false;
        }
    /*{+END}*/

    return null;
}
TagsHas Patch, Roadmap: Over the horizon
Time estimation (hours)2
Sponsorship open

Activities

Chris Graham

2023-02-23 00:26

administrator   ~0007971

This code should really be further improved. We should have a variable that tracks if the callback was called, and only call it in the setTimeout if it was not. This way if the page remains open after navigation (e.g. if opening in a new window) the callback will not happen twice.

Issue History

Date Modified Username Field Change
2023-02-21 02:12 Chris Graham New Issue
2023-02-21 02:12 Chris Graham Tag Attached: Has Patch
2023-02-21 02:12 Chris Graham Tag Attached: Roadmap: v12
2023-02-23 00:26 Chris Graham Note Added: 0007971
2024-03-26 00:58 Patrick Schmalstig Tag Renamed Roadmap: v12 => Roadmap: Over the horizon