Manage SuiteCommerce Analytics Data Cookie Preferences

The SuiteCommerce Analytics Data feature lets you track and measure user behavior and navigation on a SuiteCommerce website. As well as enabling the feature in NetSuite, you also need to install the SuiteCommerce cookie consent extension, which provides a way for shoppers to manage their consent about the use of tracking and analytics cookies on a SuiteCommerce website. If you prefer a different user experience or want to introduce additional functionality, you can create a custom extension that utilizes methods available in the extensibility API.

Note:

The API methods of the UserProfile component allow you to save and fetch cookie preferences from NetSuite. Use other JavaScript browser methods to set the cookie in the user’s browser, for example, document.cookie.

Prerequisites

Create Extension Files

Create a baseline extension to get the basic extension files and folder structure, and then create the following files.

            MyCookiesExtension
  \Modules
    \MainModule
      \JavaScript
         NetSuite.MyCookiesExtension.MainModule.js
         NetSuite.MyCookiesExtension.Banner.View.js
         NetSuite.MyCookiesExtension.Footer.View.js
      \Templates
         netsuite_mycookiesextension_banner.tpl
         netsuite_mycookiesextension_footer.tpl 

          

The following tables describes the purpose of each file in the extension.

File

Description

NetSuite.MyCookiesExtension.MainModule.js

This file is entry point file for the extension. It instantiates the required SuiteCommerce API components and loads the header and footer views.

NetSuite.MyCookiesExtension.Banner.View.js

A view that shows a form allowing website visitors to set their cookie preferences. It appears above the website header.

NetSuite.MyCookiesExtension.Footer.View.js

A view that shows a link that allows a website visitor to show the cookie banner. It appears in the footer placeholder of the website.

netsuite_mycookiesextension_banner.tpl

The template file for the banner view.

netsuite_mycookiesextension_footer.tpl

The template file for the footer view.

Update the Entry Point File

The entry point file contains the code that runs when the extension module is first mounted to the application. So, instantiate the Layout component in the entry point file to be able to add the banner and footer views to the page. You should also instantiate the UserProfile component and pass it to the instance of the banner view in an object.

When you add a view to a page with addChildView(), you must specify where on the page you want the view to be displayed. In this case, the banner view will appear at the top of the page at the Header placeholder. The footer view will appear at the bottom of the page at the Footer placeholder.

NetSuite.MyCookiesExtension.MainModule.js

            define(
  'NetSuite.MyCookiesExtension.MainModule',   
  [
    'NetSuite.MyCookiesExtension.Banner.View',
    'NetSuite.MyCookiesExtension.Footer.View'
  ],   
  function (MyCookiesExtensionBannerView, MyCookiesExtensionFooterView) {
  'use strict';

  return  {
    mountToApp: function mountToApp (container)
    {
      var layout = container.getComponent('Layout');
      var userProfile = container.getComponent('UserProfile');

      if (layout) {
        layout.addChildView('Header', function() {
          return new MyCookiesExtensionBannerView({userProfile: userProfile});
        });

        layout.addChildView('Footer', function() {
          return new MyCookiesExtensionFooterView();
        })
      }
    }
  };
}); 

          

Create a View for the Cookie Banner in the Header

The banner view contains the bulk of the logic that lets website visitors accept or reject the SuiteCommerce analytics cookie. To capture the user’s preferences, create a form that lets the shopper select which cookies they want to accept or reject. The form should let users accept or reject different types of cookies, for example, marketing cookies, performance cookies, or analytical cookies. The example code in this topic lets a website visitor accept or reject the analytical cookie only (the essential cookies cannot be rejected).

You can use the SCView class to define a view for your extension. In the view, add a reference to the template that displays a form. You can use a simple form with checkboxes or a more complex form with additional functionality or features.

The following example shows a truncated version of the view file with the truncated parts replaced with // <...>. You can read about the truncated parts below in other sections of this topic.

NetSuite.MyCookiesExtension.Banner.View.js

            define (
  'NetSuite.MyCookiesExtension.Banner.View',
  [
    'SCView', 
    'jQuery',
    'netsuite_mycookiesextension_banner.tpl'
  ],
  function(SCViewComponent, jQuery, netsuite_mycookiesextension_banner_tpl) {
    'use strict';

    var SCView = SCViewComponent.SCView;

    function MyCookiesExtensionBannerView(params) {
      SCView.call(this);

      this.template = netsuite_mycookiesextension_banner_tpl;

      this.userProfile = params.userProfile;
      var userProfile = this.userProfile;

      // Initialisation tasks. See below.
      // <...>
    }

    MyCookiesExtensionBannerView.prototype = Object.create(SCView.prototype);

    MyCookiesExtensionBannerView.prototype.constructor = MyCookiesExtensionBannerView;

    MyCookiesExtensionBannerView.prototype.getContext = function() {
      return;
    }

    MyCookiesExtensionBannerView.prototype.getEvents = function() {
      return {
        'click #myCookiesExtensionSavePreferences': 'savePrefs',
        'click #myCookiesExtensionClosePreferences': 'closePrefs',
      }
    }

    // Gets cookie preferences from the banner form. See below.
    MyCookiesExtensionBannerView.prototype.savePrefs = function() {
      // <...>
    }

    // Gets the value of the analytics cookie from the browser. See below.
    MyCookiesExtensionBannerView.prototype.getBrowserConsentCookie = function() {
      // <...>    
    }

    // Populates the cookie consent form.
    MyCookiesExtensionBannerView.prototype.populateCookiesConsentForm = function(consentCookieSettings) {
      jQuery(function() {
    }

    MyCookiesExtensionBannerView.prototype.closePrefs = function() {
      jQuery('#myCookiesExtensionBanner').hide();
        if (consentCookieSettings.ANALYTICAL == true) {
          jQuery('#myCookiesExtensionPreferenceAnalyticalCookies').prop('checked', true);
        }
      });
    }

    return MyCookiesExtensionBannerView;
  }
); 

          

Define Initialization Tasks

Add initialization tasks in the constructor function of the view. The first task is to get the browser consent cookie. If the cookie does not exist, show the cookie consent form. If the cookie does exist, check whether the browser cookie is newer than the server cookie. If the browser cookie is newer, update the server cookie and then update the browser cookie. If the browser cookie is not newer, update the browser cookie with the server cookie.

            var browserConsentCookie = this.getBrowserConsentCookie() || null;

if (browserConsentCookie) {

  // Unencode cookie
  var consentCookieData = JSON.parse(window.atob(browserConsentCookie));

  var consentCookieTimestamp = consentCookieData.timestamp;
  var consentCookieSettings = consentCookieData.consentSettings;
  var consentCookieId = consentCookieData.id;

  // Populate cookies preferences form
  this.populateCookiesConsentForm(consentCookieSettings);

  // Check if user is logged in.
  userProfile.getUserProfile().then(function(profile) {
    
    if (profile.isloggedin) {
      userProfile.getCookieOptions().then(function(cookieOptions) {

        // If the browser cookie preferences timestamp is newer than the server cookie preferences
        // timestamp, we need to update the server cookie preferences (and the browser  
        // cookie preferences thereafter).
        if (consentCookieTimestamp > cookieOptions.consentLastUpdate) {
          userProfile.setCookieOptions(consentCookieSettings).then(function(result) {
              
            // Get server cookie preferences we just set so that we can update
            // the browser cookie accordingly.
            userProfile.getCookieOptions().then(function(cookieOptions) {
                    
              var browserCookieOptions = {};

              browserCookieOptions.id = consentCookieId;
              browserCookieOptions.timestamp = cookieOptions.consentLastUpdate;
              browserCookieOptions.consentSettings = {};

              Object.keys(cookieOptions).forEach(function(k, i) {
                if (k != 'consentLastUpdate') {                                                 
                  browserCookieOptions.consentSettings[k] = i == 1 ? true : false; 
                }
              });

              var browserCookieValue = window.btoa(JSON.stringify(browserCookieOptions));
                document.cookie = "trackingConsentCookie=" + browserCookieValue;
              });

            }).catch(function(result) {
                console.log(result);
          });
        }
        else {
          // If the server cookie preferences are newer, update the browser cookie.
          MyCookiesExtensionBannerView.prototype.setBrowserConsentCookie(cookieOptions);
          MyCookiesExtensionBannerView.prototype.populateCookiesConsentForm();
        }
      });
    }
    else {
      console.log('User not logged in. Nothing to do. :-(');
    }               
  });
}
else {
  jQuery(function() {
    jQuery('#myCookiesExtensionBanner').show();
  });
} 

          

Get or Set the Browser Cookie

When the extension loads, check if the browser consent cookie specific to SuiteCommerce Analytics Data exists and return its value with the getBrowserConsentCookie() function. The consent cookie name should be 'trackingConsentCookie' and its value should be a Base64-encoded string.

The following example shows one way to get the browser cookie.

            MyCookiesExtensionBannerView.prototype.getBrowserConsentCookie = function() {
  var cookies = document.cookie.split(';');
  var browserConsentCookie = null;

  var browserConsentCookie = cookies.find(function(element) {   
    if (element.trim().startsWith('trackingConsentCookie')) {
      return element;
    }
  });

  if (browserConsentCookie) {
    var consentCookieValueStart = browserConsentCookie.indexOf('=');
    browserConsentCookie = browserConsentCookie.substring(consentCookieValueStart + 1);

    if (browserConsentCookie.length > 0) {
      return browserConsentCookie;
    }
  }
} 

          

The following example shows one way to set the browser cookie.

            MyCookiesExtensionBannerView.prototype.setBrowserConsentCookie = function(cookieOptions) {
  var browserCookieOptions = {};

  browserCookieOptions.id = consentCookieId;
  browserCookieOptions.timestamp = cookieOptions.consentLastUpdate;
  browserCookieOptions.consentSettings = {};

  Object.keys(cookieOptions).forEach(function(k, i) {
    if (k != 'consentLastUpdate') {
      browserCookieOptions.consentSettings[k] = i == 1 ? true : false;
    }
  }

  var browserCookieValue = window.btoa(JSON.stringify(browserCookieOptions));

  document.cookie = "trackingConsentCookie=" + browserCookieValue
} 

          

Get and Format Consent Cookie Preferences

When the website visitor clicks the Save button, get the visitor's preferences from the form and create an object that contains the preferences in the correct format. The savePrefs() function (see below) gets the form values in the banner, creates a cookie preferences object, and encodes the object to a Base64 string. The cookie preferences object must be in the following format:

            {
  id: <id>,
  timestamp: <timeStamp>,
  consentsettings: {<preferenceName>: <preferenceValue>, <...>}
} 

          
  • id - A unique ID as a string. You can generate an ID by concatenating the value of timestamp and the browser user agent.

  • timestamp - A timestamp generated by Date.now().

  • consentsettings - An object that contains a list of key/value pairs, each of which corresponds to a cookie preference name <preferenceName>, and its value <preferenceValue>. The value must be a boolean - true or false.

You can include any number of cookie preferences in the consentsettings property of the object. It is important, however, that the name of the cookie preference for analytics tracking is 'ANALYTICAL'. Using any other name for the analytical cookie will be ignored. Additionally, the SuiteCommerce Analytics Data feature only tracks user behavior and navigation if the value of ANALYTICAL is true.

Then create a Base64-encoded string from the object and save the preferences with the setCookiePreferences() function. Hide the banner to indicate the website visitor's preferences have been saved. The visitor can show the banner again by clicking the link in the footer.

            MyCookiesExtensionBannerView.prototype.savePrefs = function() {
         
  var cookieConsentPreferences = {};
  var cookieOptions = {};
      
  var now = Date.now();
  var browserUserAgent = navigator.userAgent.replaceAll(' ', '');
      
  // Get form values
  cookieConsentPreferences.ANALYTICAL = jQuery('#myCookiesExtensionPreferenceAnalyticalCookies').is(':checked') ? true : false;
  cookieConsentPreferences.ESSENTIAL = true;

  cookieOptions.id = now + browserUserAgent;
  cookieOptions.timestamp = now;
  cookieOptions.consentSettings = cookieConsentPreferences;

  var browserCookieValue = window.btoa(JSON.stringify(cookieOptions));
      
  // Try to set cookie options. If the user is logged in, cookies can be set on the server side. 
         
  if (this.userProfile) {            
    this.setCookiePreferences(cookieOptions, browserCookieValue);
  }

  jQuery('#myCookiesExtensionBanner').hide(); 
} 

          

Persist Cookie Preferences in NetSuite

To save the visitor's preferences in NetSuite, create a separate function in the banner view called setCookiePreferences() with two arguments. The first argument you pass to the function is an object that contains the visitor's preferences in the format required to save the object on the server side. The second argument is the Base64-encoded string of the visitor's preferences that will be saved on the client side in a cookie.

In the setCookiePreferences() function, use the setCookieOptions() method of the UserProfile component to save the visitor's consent preferences. The method returns a promise, which if resolved, indicates that the consent preferences were saved successfully.

            MyCookiesExtensionBannerView.prototype.setCookiePreferences = function(cookieOptions, browserCookieValue) {
  var nlrum = window.NLRUM || null;
  var actionId = null;

  if (nlrum) {
    actionId = nlrum.actionStart('Accept Privacy Consent');
  }

  this.userProfile.setCookieOptions(cookieOptions.consentSettings).then(function(result) {
    console.log('setCookieOptions was successful.');            
  }).catch(function() {
    console.log('setCookieOptions failed.');
  }).always(function() {
    document.cookie = "trackingConsentCookie=" + browserCookieValue;

  if (nlrum) {

    function getCookieOptions() {
      var browserConsentCookie = MyCookiesExtensionBannerView.prototype.getBrowserConsentCookie() || null;
      var consentCookieData = JSON.parse(window.atob(browserConsentCookie));

      if (consentCookieData) {
        return {
          id: consentCookieData.id,
          timestamp: consentCookieData.timestamp,
          consentSettings: formatCookieOptions(consentCookieData.consentSettings)
        };
      }
      return null;
    }

    function formatCookieOptions(cookieOptions){
      let options = [];
                  
      Object.keys(cookieOptions).forEach(
        (option) => {
          options.push(option + '|' + (cookieOptions[option] ? 'T' : 'F'));
        }
      )
      
      return options.join(',');
    }

    var actionData = {
      siteUrl: window.location.hostname,
      shopperAnalyticsConsent: getCookieOptions()
    };            

    nlrum.actionEnd(actionId, actionData);
  }            
}); 

          

The setCookieOptions() method only works if the website is on a secure connection (HTTPS) and if the user is logged in. If either of the conditions is not met, the method fails and returns a rejected promise. Even if the consent preferences cannot be saved in NetSuite, the setCookiePreferences() function sets the cookie on the client side. When the user logs in successfully the next time, the user's preferences will be saved in NetSuite, provided the cookie still exists.

When saving cookie consent preferences in NetSuite, you can also log the action in Application Performance Management (APM) for Commerce. Use the window.NLRUM object to log the action. You must first create an action ID by calling actionStart() with the string 'Accept Privacy Consent 'as its argument. Using any other string will be ignored by APM. Then call actionEnd(), passing in the action ID and the visitor's cookie preferences in the required format.

            {
  siteUrl: shop.netsuite.com,
  shopperAnalyticsConsent: {
    id: "1648808771790Mozilla/5.0(WindowsNT10.0;Win64;x64;rv:98.0)Gecko/20100101Firefox/98.0",
    timestamp: 1648808771790,
    consentSettings: "ESSENTIAL|T,ANALYTICAL|T"
  }
}; 

          

See Application Performance Management (APM) for Commerce for more information about installing and using APM.

Finally, the banner view requires a template to render the cookie preferences form.

netsuite_mycookiesextension_banner.tpl

            <div id="myCookiesExtensionBanner" class="" style="display: none; margin-left: 20px; padding: 10px;">
  <div>We use cookies!  </div>
  <form>
    <input type="checkbox" id="myCookiesExtensionPreferenceEssentialCookies" name="ESSENTIAL" checked="" disabled=""> <b>Essential</b> - These cookies are required for the website to function correctly.<br>
    <input type="checkbox" id="myCookiesExtensionPreferenceAnalyticalCookies" name="ANALYTICAL"> <b>Analytical</b> - We use analytical cookies to measure your interaction on the website when you are logged in so that we can improve your shopping experience. For more information, see our <a href="#">Cookies Policy</a>.<br>
    <input type="button" id="myCookiesExtensionSavePreferences" style="background-color: rgb(21,111,144); color: white; font-weight: bold; float: left; width: 100px" value="Save"> <input type="button" id="myCookiesExtensionClosePreferences" style="background-color: white; color: rgb(21,111,144); display: inline; font-weight: bold; margin-left: 16px; width: 100px" value="Close">
  </form>
</div> 

          

Create a View for the Footer

The view for the footer is a relatively simple view that shows a link in the footer area of the website. Clicking the link shows the cookies banner in the header and scrolls the page to the top. To add an event listener for the click event on the link, use getEvents() to define the event listener and the event handler. The event handler is a short function that uses jQuery to show the banner's div element.

            define('NetSuite.MyCookiesExtension.Footer.View',   
  [
    'SCView',
    'jQuery',
    'netsuite_mycookiesextension_footer.tpl'
  ], 
  function (SCViewComponent, jQuery, netsuite_mycookiesextension_footer_tpl) {
    'use strict';
      
    var SCView = SCViewComponent.SCView;
      
    function MyCookiesExtensionFooterView() {
      SCView.call(this);
         
      this.template = netsuite_mycookiesextension_footer_tpl;      
    }
      
    MyCookiesExtensionFooterView.prototype = Object.create(SCView.prototype);

    MyCookiesExtensionFooterView.prototype.constructor = MyCookiesExtensionFooterView;

    MyCookiesExtensionFooterView.prototype.getContext = function() {
      return;
    }
      
    MyCookiesExtensionFooterView.prototype.getEvents = function() {
      return {
     'click #myCookiesExtensionCookiesLink': 'showCookiesBanner' 
      }
    }
      
    MyCookiesExtensionFooterView.prototype.showCookiesBanner = function() {
      jQuery('#myCookiesExtensionBanner').show();
      window.scrollTo(0,0);
    }
      
    return MyCookiesExtensionFooterView;
  }
); 

          

The footer view requires a template to show a link that displays the consent form.

netsuite_mycookiesextension_footer.tpl

            <div id="myCookiesExtensionFooter" class="" style="display: block; margin-left: 20px; padding: 10px;">
  <a href="#" id="myCookiesExtensionCookiesLink">Cookies Policy  </a></div>
</div> 

          

Related Topics

General Notices