Enable Google Analytics 4 (SCA 2019.2 – 2022.1)

Prepare your SuiteCommerce Advanced (SCA) implementation of Google Analytics 4 (GA4) without Google Tag Manager (GTM) as described in the following steps. You need to create new folders, files, and modules, so be sure to complete all of the required steps as outlined in the following procedures:

Prepare GoogleAnalytics4 Folders Structure

  1. Go to .../SC_XX.X(_Live)/Advanced where XX.X is your version of SCA. The _Live folder will be present depending on your version of SCA.

  2. In the Advanced folder, create a new folder called, GoogleAnalytics4.

  3. In the GoogleAnalytics4 folder, create folders and files using the following structure:

                    SC_XX.X(_Live)/
    └── Advanced/
        └── GoogleAnalytics4/
            ├── Configuration/
            │   └── GoogleAnalytics4.json
            ├── JavaScript/
            │   └── GoogleAnalytics4.ts
            └── ns.package.json 
    
                  

Create GoogleAnalytics4.json File

  1. Go to the Configuration folder in the structure you created in Prepare GoogleAnalytics4 Folders Structure.

  2. Create and save the GoogleAnalytics4.json file with the following code:

                    {
        "type": "object",
        "subtab": {
            "id": "analyticsFour",
            "title": "Google Analytics 4",
            "docRef": "bridgehead_4667032443",
            "description": "Google Analytics 4",
            "group": "integrations"
        },
        "properties": {
            "tracking.googleAnalyticsFour.propertyID": {
                "group": "integrations",
                "subtab": "analyticsFour",
                "type": "string",
                "title": "Google Analytics 4 ID",
                "description": "Enter the Google Analytics 4 Tracking ID. SuiteCommerce Advanced inserts this property into each page of the application. To locate the tracking ID, login to your Google Analytics 4 account and go to Admin > Data Streams > select your data stream > MEASUREMENT ID.",
                "default": ""
            },
            "tracking.googleAnalyticsFour.domainName": {
                "group": "integrations",
                "subtab": "analyticsFour",
                "type": "string",
                "title": "Google Analytics 4 domain",
                "description": "Enter the domain used for Google Analytics. The value you enter depends on which application you want to use Google Analytics",
                "default": ""
            },
            "tracking.googleAnalyticsFour.domainNameSecure": {
                "group": "integrations",
                "subtab": "analyticsFour",
                "type": "string",
                "title": "Google Analytics 4 secure domain",
                "description": "Enter the secure domain used for Google Analytics 4. Possible values are the same as the Google Analytics Domain property.",
                "default": ""
            }
        }
    } 
    
                  

Create GoogleAnalytics4.ts File

  1. Go to the JavaScript folder in the structure you created in Prepare GoogleAnalytics4 Folders Structure.

  2. Create the TypeScript file, GoogleAnalytics4.ts, with the following code:

                    /// <amd-module name="GoogleAnalytics4"/>
    
    /* Same imports as in the file Advanced\GoogleUniversalAnalytics\JavaScript\GoogleUniversalAnalytics.ts */
    
    export = (function(win: any, name) {
        // @class GoogleAnalytics4 @extends ApplicationModule
        // ------------------
        // Loads google analytics 4 script and extends application with methods:
        // * trackPageview
        // * trackEvent
        // * trackTransaction
        // Also wraps layout's showInModal
    
        interface GA4Options {
            send_page_view?: boolean;
            client_id?: string;
            session_id?: string;
        }
    
        const dataLayerName = name + 'DataLayer';
    
        const GoogleAnalytics4: any = {
            // @method doCallback Indicates if this module do a callback after some particular events
            // @return {Boolean}
            doCallback: function() {
                return !!win[name];
            },
    
            // @method trackPageview
            // @param {String} url
            // @return {GoogleAnalytics4}
            trackPageview: function(url) {
                if (_.isString(url)) {
                    url = url.split('?')[0];
                    win.gtag('event', 'page_view', { page_location: url, page_title: url });
                }
    
                return this;
            },
    
            trackLogin: function(event) {
                win.gtag('event', 'login', { method: event.category, event_callback: event.callback });
    
                return this;
            },
    
            trackRegister: function(event) {
                win.gtag('event', 'sign_up', {
                    method: event.category,
                    event_callback: event.callback
                });
    
                return this;
            },
            trackCheckoutAsGuest: function(event) {
                win.gtag('event', 'checkout_as_guest', {
                    method: event.category,
                    event_callback: event.callback
                });
    
                return this;
            },
    
            // @method trackEvent
            // @param {TrackEvent} event
            // @return {GoogleAnalytics}
            trackEvent: function(event) {
                if (event && event.category && event.action) {
                    win.gtag('event', 'generic_event', {
                        category: event.category,
                        action: event.action,
                        label: event.label,
                        value: parseFloat(event.value) || 0,
                        page: event.page || '/' + Backbone.history.fragment,
                        event_callback: event.callback
                    });
                }
    
                return this;
            },
    
            // @method trackTransaction
            // Based on the created SalesOrder we trigger each of the analytics
            // ecommerce methods passing the required information
            // @param {Tracker.Transaction.Model} @extends Backbone.Model transaction
            // @return {GoogleAnalytics|Void}
            trackTransaction: function(transaction) {
                const transaction_id = transaction.get('confirmationNumber');
    
                const purchase = {
                    transaction_id: transaction_id,
                    value: transaction.get('subTotal'),
                    tax: transaction.get('taxTotal'),
                    shipping: transaction.get('shippingCost') + transaction.get('handlingCost'),
                    currency:
                        (SC.ENVIRONMENT.currentCurrency && SC.ENVIRONMENT.currentCurrency.code) || '',
                    affiliation: Configuration.get('siteSettings.displayname'),
                    items: []
                };
    
                transaction.get('products').each(function(product, index) {
                    purchase.items.push({
                        item_id: product.get('id'),
                        item_name: product.get('name'),
                        affiliation: Configuration.get('siteSettings.displayname'),
                        currency:
                            (SC.ENVIRONMENT.currentCurrency && SC.ENVIRONMENT.currentCurrency.code) ||
                            '',
                        index: index,
                        item_category: product.get('category') || '',
                        item_variant: product.get('options'),
                        price: product.get('rate'),
                        quantity: product.get('quantity')
                    });
                });
    
                win.gtag('event', 'purchase', purchase);
    
                return this;
            },
    
            // @method addCrossDomainParameters
            // @param {string} url
            // @return {String} url
            addCrossDomainParameters: function(url) {
                // We only need to add the parameters if the URL we are trying to go
                // is not a sub domain of the tracking domain
                if (_.isString(url)) {
                    url = Utils.addParamsToUrl(url, {
                        client_id: win[name].client_id,
                        session_id: win[name].session_id
                    });
                }
    
                return url;
            },
    
            // @method loadScript
            // @return {jQuery.Promise|Void}
            loadScript: function(id: string) {
                return jQuery.getScript(
                    `//www.googletagmanager.com/gtag/js?id=${id}&l=${dataLayerName}`
                );
            },
    
            // @method mountToApp
            // @param {ApplicationSkeleton} application
            // @return {Void}
            mountToApp: function(application) {
                const tracking = Configuration.get('tracking.googleAnalyticsFour');
    
                // if track page view needs to be tracked
                if (tracking && tracking.propertyID && !SC.isPageGenerator()) {
                    win[dataLayerName] = win[dataLayerName] || [];
                    win.gtag =
                        win.gtag ||
                        function() {
                            win[dataLayerName].push(arguments);
                        };
                    const domains = [];
                    if (tracking.domainName) {
                        domains.push(tracking.domainName);
                    }
                    if (tracking.domainNameSecure) {
                        domains.push(tracking.domainNameSecure);
                    }
    
                    if (domains.length) {
                        win.gtag('set', 'linker', {
                            domains: domains
                        });
                    }
    
                    const configOptions: GA4Options = {
                        send_page_view: false
                    };
    
                    const client_id = Utils.getParameterByName(win.location.href, 'client_id');
                    const session_id = Utils.getParameterByName(win.location.href, 'session_id');
    
                    if (client_id && session_id) {
                        configOptions.client_id = client_id;
                        configOptions.session_id = session_id;
                    }
    
                    win.gtag('js', new Date());
                    win.gtag('config', tracking.propertyID, configOptions);
    
                    // Please keep this statement here or the first pageView on site load
                    // will not be triggered (ApplicationSkeleton.Layout._showContent)
                    Tracker.getInstance().trackers.push(GoogleAnalytics4);
    
                    // the analytics script is only loaded if we are on a browser
                    application.getLayout().once('afterAppendView', function() {
                        GoogleAnalytics4.loadScript(tracking.propertyID)
                            .done(function() {
                                win[name] = {};
                                win.gtag('get', tracking.propertyID, 'client_id', client_id => {
                                    win[name].client_id = client_id;
                                });
                                win.gtag('get', tracking.propertyID, 'session_id', session_id => {
                                    win[name].session_id = session_id;
                                });
                            })
                            .fail(function(jqXhr) {
                                jqXhr.preventDefault = true;
                                console.warn('Google Analytics 4 was unable to load');
                            });
                    });
                }
            }
        };
    
        return GoogleAnalytics4;
    })(window, 'ga4'); 
    
                  
  3. Open the file, .../Advanced/GoogleUniversalAnalytics/JavaScript/GoogleUniversalAnalytics.ts and copy the imports.

  4. In the GoogleAnalitycs4.ts file, find the following comment:

                    /* Same imports as in the file Advanced\GoogleUniversalAnalytics\JavaScript\GoogleUniversalAnalytics.ts */ 
    
                  

    And replace it with the imports you copied.

    The following sample shows what the imports might look like:

                    import * as _ from 'underscore';
    import * as Utils from '../../../Commons/Utilities/JavaScript/Utils';
    import * as jQuery from '../../../Commons/Core/JavaScript/jQuery';
    import { Configuration } from '../../SCA/JavaScript/Configuration';
    
    import Tracker = require('../../../Commons/Tracker/JavaScript/Tracker');
    import Backbone = require('../../../Commons/Utilities/JavaScript/backbone.custom'); 
    
                  
  5. Save the GoogleAnalitycs4.ts file.

Create ns.package.json File

  1. Go to the GoogleAnalytics4 folder in the structure you created in Prepare GoogleAnalytics4 Folders Structure.

  2. Create and save the json file, ns.package.json, with the following code:

                    {
        "gulp": {
            "javascript": ["JavaScript/*.ts"],
            "configuration": ["Configuration/*.json"]
        }
    } 
    
                  

Add GoogleAnalytics4 Module

  1. Open the distro.json file in the .../Advanced directory and add GoogleAnalytics4 to the list of modules. The following sample shows the value to add to the list of existing values that follow the “modules” key:

                    {
       ...
       "modules": [
          "GoogleAnalytics4",
          ...
       ],
       ...
    } 
    
                  
  2. Save your changes.

Add entryPoints Module to Application Dependencies

  1. Open the distro.json file in the .../Advanced directory and verify if the entryPoints modules for the Shopping, Checkout, and MyAccount applications have dependencies attributes.

    The following sample shows what the entryPoints code will look like for the Shopping application:

                    {
       ...
        "tasksConfig": {
          ...
            "javascript": {
                "entryPoints": [
                    {
                        "names": ["SC.Shopping.Starter.js"],
                        "exportFile": "shopping.js",
                        "dependencies": [
                            ...
                        ]
                    },
                ...
             ...
          ...
       ...
    } 
    
                  
  2. Add “GoogleAnalytics4” to the list of dependencies for each application.

    The following sample shows what your updated code will look like for the Shopping application:

                    {
       ...
        "tasksConfig": {
          ...
            "javascript": {
                "entryPoints": [
                    {
                        "names": ["SC.Shopping.Starter.js"],
                        "exportFile": "shopping.js",
                        "dependencies": [
                            "GoogleAnalytics4",
                            ...
                        ]
                    },
                ...
             ...
          ...
       ...
    } 
    
                  
  3. Save the distro.json file.

  4. If the entryPoints modules for the Shopping, Checkout, and MyAccount applications do not have dependencies attributes, you need to update the dependencies files for each application.

  5. Go to …/Advanced/CheckoutApplication/JavaScript/ and open the TypeScript file, SC.Checkout.Starter.Dependencies.ts.

  6. Add the following import:

                    import GoogleAnalytics4 = require('../../GoogleAnalytics4/JavaScript/GoogleAnalytics4'); 
    
                  
  7. Add the following dependency to the entryPointModules array:

                    export const entryPointModules = [
    GoogleAnalytics4,
    ...
    ] 
    
                  
  8. Save the SC.Checkout.Starter.Dependencies.ts file.

  9. Go to …/Advanced/ShoppingApplication/JavaScript and open the TypeScript file SC.Shopping.Starter.Dependencies.ts.

  10. Add the following import:

                    import GoogleAnalytics4 = require('../../GoogleAnalytics4/JavaScript/GoogleAnalytics4'); 
    
                  
  11. Add the following dependency to the entryPointModules array:

                    export const entryPointModules = [
    GoogleAnalytics4,
    ...
    ] 
    
                  
  12. Save the SC.Shopping.Starter.Dependencies.ts file.

  13. Go to …/Advanced/MyAccountApplication.SCA/JavaScript and open the TypeScript file, SC.MyAccount.Starter.Dependencies.ts.

  14. Add the following import:

                    import GoogleAnalytics4 = require('../../GoogleAnalytics4/JavaScript/GoogleAnalytics4'); 
    
                  
  15. Add the following dependency to the entryPointModules array:

                    export const entryPointModules = [
    GoogleAnalytics4,
    ...
    ] 
    
                  
  16. Save the SC.MyAccount.Starter.Dependencies.ts file.

Test and Deploy Your Customizations

Follow the instructions provided in Test SCA Customizations on a Local Server and Deploy SCA Customizations to NetSuite to test and deploy your customizations.

Related Topics

Guide to Enable Google Analytics 4
Enable Google Analytics 4 (SCA Vinson – 2019.1)
Enable Google Analytics 4 (Denali – Mont Blanc)

General Notices