View Issue Details

IDProjectCategoryView StatusLast Update
5340Composrcorepublic2023-02-23 00:26
ReporterChris Graham Assigned ToGuest  
PrioritynormalSeverityfeature 
Status newResolutionopen 
Summary5340: 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
Attach Tags
Time estimation (hours)2
Sponsorship open

Sponsor

Date Added Member Amount Sponsored

Activities

Chris Graham

2023-02-23 00:26

administrator   ~7971

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.

Add Note

View Status
Note
Upload Files
Maximum size: 32,768 KiB

Attach files by dragging & dropping, selecting or pasting them.
You are not logged in You are not logged in. This means you will not get any e-mail notifications. And if you reply, we will not know for sure you are the original poster of the issue.

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 PDStig Tag Renamed Roadmap: v12 => Roadmap: Over the horizon