Skip to content

arsari/AnalyticsWeb

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AnalyticsWeb

AnalyticsWeb Releases-Tags    MIT License
AnalyticsMobile

Web Analytics Implementation Playground

Table of Contents

[[TOC]]

Introduction

Google Analytics 4 (GA4) and Adobe Analytics (AA) are the most used tools for a comprehensive and flexible approach to website and apps analytics. Amplitude Analytics and Mixpanel Product Analytics are two other tools that lets you answer questions, make better decisions and drive outcomes with product analytics. For any of the aforementioned tools, to do an implementation on our website, will need to follow these steps:

  1. Create an account or property in the corresponding tool account.
  2. Install the tool tracking code or instrumentation on our website.
  3. Verify the tool installation.
  4. Configure tool reports, analysis workspace, and dashboard settings.
  5. Start tracking our website traffic.

This is a playground of analytic implementation for a website using GTM and a GA4 web data stream, Tealium iQ and Adobe Analytics, Amplitude Analytics, and Mixpanel Product Analytics. The implementation allows to explore:

  • a dataLayer array-objects managed through GTM and analyzing the data in a GA4 web data stream,
  • a utag_data variable object and utag.link() data objects managed through Tealium iQ tag management and analyzing the data in Adobe Analytics.
  • Amplitude data objects to analyze the data in Amplitude Analytics.
  • Mixpanel data object to analyze data in Mixpanel Product Analytics.
  • an initial setup of Adobe Launch rules to see response in the browser console (experimental implementation).

Before we start with the playground set up and back end, we should already have a GTM container linked to a Google Analytics 4 web data stream, a Tealium iQ account setup with AA tag, an Adobe Analytics account, an Amplitude Analytics account, and a Mixpanel Product Analytics account. Having them created and configured will facilitate the use of playground as a data source for the tools.

Playground Screenshot

Tagging Strategy and Implementation

The implementation fires an initial dataLayer object (GTM), utag_data object variable (TiQ) and an enrichEventsPlugin function (Amplitude), and a page view track for Mixapanel on each website page.

The dataLayer array-object should be located inside the <head>...</head> tag of the web page before the GTM snippet.

<!-- dataLayers message -->
<script type="text/javascript">
  const userInit = localStorage.UUID ?? "guest";
  window.dataLayer = window.dataLayer || [];
  window.dataLayer.push({
    page_title: document.querySelector("title").innerText,
    page_name: "Web Analytics Implementation - Home Page",
    page_category: "home",
    page_author: "Arturo Santiago-Rivera",
    author_email: "asantiago@arsari.com",
    content_group: "Implementation",
    content_type: "Playground",
    language_code: "en-US",
    e_timestamp: String(new Date().getTime()), // milliseconds
    // user properties
    logged_in: false,
    user_id: userInit,
  });
</script>
<!-- END: dataLayers message -->

The utag_data variable should be located inside the <body>...</body> tag of the web page before the Tealium IQ snippet.

<!-- utag data object message -->
<script type="text/javascript">
  const utag_data = {
    page_title: document.querySelector("title").innerText,
    page_name: "Web Analytics Implementation - Home Page",
    page_category: "home",
    page_author: "Arturo Santiago-Rivera",
    author_email: "asantiago@arsari.com",
    content_group: "Implementation",
    content_type: "Playground",
    language_code: "en-US",
    e_timestamp: String(new Date().getTime()), // milliseconds
    // user properties
    logged_in: false,
    user_id: userInit,
    custom_user_id: userInit,
  };
</script>
<!-- END: utag data object message -->

The Amplitude data object should be located inside the <head>...</head> tag of the web page after the Amplitude snippet but before to their statement of initialization. The initial Amplitude data object, that include events properties applicable to all the events, is coded in an enrich plugin variable.

<!-- amplitude global properties and initialization -->
<script type="text/javascript">
    const enrichEventsPlugin = () => ({
        execute: async (event) => {
          event.event_properties = {
            ...event.event_properties,
            page_title: document.querySelector('title').innerText,
            page_name: 'Web Analytics Implementation - Home Page',
            page_category: 'home',
            page_author: 'Arturo Santiago-Rivera',
            author_email: 'asantiago@arsari.com',
            content_group: 'Implementation',
            content_type: 'Playground',
            language_code: 'en-US',
            env_viewed: tealiumEnv,
          };
          return event;
        },
    });
    amplitude.add(enrichEventsPlugin()); // amplitude enrich plugin call
    amplitude.init(<<AMPLITUDE_API_KEY>>, userInit); // amplitude init statement
</script>
<!-- END: amplitude global properties and initialization -->

The Mixpanel data object should be located inside the <head>...</head> tag of the web page after the Mixpanel statement of initialization and after the user identify method. The initial Mixpanel data object, that include events properties applicable to all the events, is coded in an mixpanel.register() method. User identification and suer properties are coded in mixpanel.identify() method and mixpanel.people.set() method.

<!-- mixpanel initialization and global properties -->
<script type="text/javascript">
    mixpanel.init(<<MIXPANEL_API_KEY>>); // mixpanel init statement
    mixpanel.identify(userInit); // mixpanel user identify
    mixpanel.people.set({ logged_in: false }); // mixpanel user properties
    mixpanel.register({
      page_title: document.querySelector("title").innerText,
      page_name: "Web Analytics Implementation - Home Page",
      page_category: "home",
      page_author: "Arturo Santiago-Rivera",
      author_email: "asantiago@arsari.com",
      content_group: "Implementation",
      content_type: "Playground",
      language_code: "en-US",
      env_viewed: tealiumEnv,
    });
    mixpanel.track_pageview({
      e_timestamp: String(new Date().getTime()), // milliseconds
    });
</script>
<!-- END: mixpanel initialization and global properties -->

The tagging implementation for events consider the followings user actions (ui interactions), system events (content tools), and errors based on an element click attribute [name="action"] and a addEventListener() method to fire the corresponding events:

User Action Event Name Type Parameters/Event Properties GA4 Scope GA4 Custom Definitions
Sign In login user interaction method Event Predefined
Outbound Link outbound_link user interaction link_domain
link_classes
link_id
link_url
link_text
outbound
Event
Event
Event
Event
Event
Event
Predefined
Predefined
Predefined
Predefined
Predefined
Predefined
Internal Link internal_link user interaction link_domain
link_classes
link_id
link_url
link_text
Event
Event
Event
Event
Event
Predefined
Predefined
Predefined
Predefined
Predefined
Download file_download user interaction file_name
file_extension
link_domain
link_classes
link_id
link_text
Event
Event
Event
Event
Event
Event
Predefined
Predefined
Predefined
Predefined
Predefined
Predefined
Video video_start user interaction video_duration
video_current_time
video_percent
video_status
video_provider
video_title
video_url
Event
Event
Event
Event
Event
Event
Event
Metric (sec)
Metric (sec)
Dimension
Dimension
Predefined
Predefined
Predefined
Video Playing video_progress content tool video_duration
video_current_time
video_percent
video_status
video_provider
video_title
video_url
Event
Event
Event
Event
Event
Event
Event
Metric (sec)
Metric (sec)
Dimension
Dimension
Predefined
Predefined
Predefined
Video Playing video_complete content tool video_duration
video_current_time
video_percent
video_status
video_provider
video_title
video_url
Event
Event
Event
Event
Event
Event
Event
Metric (sec)
Metric (sec)
Dimension
Dimension
Predefined
Predefined
Predefined
Video playing video_stop user interaction video_duration
video_current_time
video_percent
video_status
video_provider
video_title
video_url
Event
Event
Event
Event
Event
Event
Event
Metric (sec)
Metric (sec)
Dimension
Dimension
Predefined
Predefined
Predefined
Email generate_lead user interaction contact_method
currency
value
Event
Event
Event
Dimension
Predefined
Predefined
Phone generate_lead user interaction contact_method
currency
value
Event
Event
Event
Dimension
Predefined
Predefined
Form form_start user interaction form_destination
form_id
form_name
Event
Event
Event
Dimension
Dimension
Dimension
* Submit Button form_submit user interaction contact_method
form_destination
form_id
form_name
form_submit_text
value
user_profession
Event
Event
Event
Event
Event
Event
Event
Dimension
Dimension
Dimension
Dimension
Dimension
Predefined
Dimension
* Close form_modal_closed user interaction form_id
form_name
Event
Event
Dimension
Dimension
Form form_error content tool error_message
alert_impression
Event
Event
Dimension
Dimension
Ecommerce Funnel ecommerce_modal_opened user interaction
Ecommerce Funnel view_item_list content tool ecommerce.item_list_id
ecommerce.item_list_name
ecommerce.items
Event
Event
Event
Predefined
Predefined
Predefined
Ecommerce Funnel select_item user interaction ecommerce.item_list_id
ecommerce.item_list_name
ecommerce.items
Event
Event
Event
Predefined
Predefined
Predefined
Ecommerce Funnel add_to_cart user interaction ecommerce.currency
ecommerce.value
ecommerce.items
Event
Event
Event
Predifined
Predifined
Predifined
Ecommerce Funnel view_cart content tool ecommerce.currency
ecommerce.value
ecommerce.items
Event
Event
Event
Predifined
Predifined
Predifined
Ecommerce Funnel remove_from_cart user interaction alert_message
alert_impression
ecommerce.currency
ecommerce.value
ecommerce.items
Event
Event
Event
Event
Event
Dimension
Dimension
Predifined
Predifined
Predifined
Ecommerce Funnel begin_checkout user interaction ecommerce.currency
ecommerce.value
ecommerce.coupon
ecommerce.items
Event
Event
Event
Event
Predifined
Predifined
Predifined
Predifined
Ecommerce Funnel add_shipping_info user interaction ecommerce.currency
ecommerce.value
ecommerce.coupon
ecommerce.shipping_tier
ecommerce.items
Event
Event
Event
Event
Event
Predifined
Predifined
Predifined
Predifined
Predifined
Ecommerce Funnel add_payment_info user interaction ecommerce.currency
ecommerce.value
ecommerce.coupon
ecommerce.payment_type
ecommerce.items
Event
Event
Event
Event
Event
Predifined
Predifined
Predifined
Predifined
Predifined
Ecommerce Funnel purchase user interaction ecommerce.transaction_id
ecommerce.currency
ecommerce.value
ecommerce.tax
ecommerce.shipping
ecommerce.coupon
ecommerce.shipping_tier
ecommerce.items
Event
Event
Event
Event
Event
Event
Event
Event
Predifined
Predifined
Predifined
Predifined
Predifined
Predifined
Predifined
Predifined
Ecommerce Funnel refund user interaction ecommerce.transaction_id
ecommerce.currency
ecommerce.value
ecommerce.tax
ecommerce.shipping
ecommerce.coupon
ecommerce.items
Event
Event
Event
Event
Event
Event
Event
Predifined
Predifined
Predifined
Predifined
Predifined
Predifined
Predifined
Ecommerce Funnel <ecommerce events>_error content tool error_message
alert_impression
step
Event
Event
Event
Dimension
Dimension
Dimension
* Cancel ecommerce_modal_closed user interaction
Search search_modal_opened user interaction
* Magnified Glass search user interaction search_term Event Predefined
* Close search_modal_closed user interaction
Search search_error content tool error_message
alert_impression
Event
Event
Dimension
Dimension
Sign Out logout user interaction Event Dimension

The following global parameters/event properties apply to most of the above events:

Global Parameters/Event Properties GA4 Scope GA4 Custom Definitions
event_id (gtm config parameter) Event Dimension
event_type Event Dimension
button_text Event Dimension
tag_name Event Dimension
env_viewed (amplitude & mixpanel) n/a n/a
step (ecommerce events only) Event Dimension
section_heading (ecommerce events only) Event Dimension
e_timestamp (milliseconds) Event Dimension
custom_timestamp (ISO 8601) Event Dimension
custom_user_id (user Property) User Dimension
logged_in (user property) User Dimension
user_id (user property) User Predefined

On Amplitude Analytics, the event name is modified in the events list of the Amplitude dashboard as noun+verb capitalizing each word. The event properties naming is sneak_case.

The events dataLayer array-object is based on Google Analytics 4 events recommendations and Google Tag Manager dataLayer. The utag.link data object is based on the Tealium utag.link and Adobe Analytics objects. The Amplitude Analytics data object is based on the Amplitude source Browser SDK 2.0.

We classified the implementation of the dataLayer[] array-object, utag.link() data object, and amplitude.track() and mixpanel.track() data object into the following event groups:

General Events

The implemented general events dataLayer array-object, utag.link data object, and amplitude.track data object is composed of:

dataLayer.push()
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
  event: en || e.id,
  // event parameters
  button_text:
    e.tagName === "BUTTON" && e.innerText !== "" ? e.innerText : undefined,
  contact_method: cm,
  currency: cc,
  event_type: /generate_lead|form_submit/.test(en)
    ? "conversion"
    : "ui interaction",
  file_extension: e.id === "download" ? "pdf" : undefined,
  file_name: e.id === "download" ? "PDF_to_Download" : undefined,
  form_destination: fd,
  form_id: e.id.includes("form") ? e.id : undefined,
  form_name: e.id.includes("form") ? "User Profession Survey" : undefined,
  form_submit_text: e.id === "form" ? e.innerText : undefined,
  link_domain: ld,
  link_classes: lc,
  link_id: /extlink|intlink|download|banner/.test(e.id) ? e.id : undefined,
  link_url: lu,
  link_text: /extlink|intlink|download|banner/.test(e.id)
    ? e.innerText
    : undefined,
  method: e.id === "login" ? "Google" : undefined,
  outbound: ol,
  search_term: st,
  tag_name: e.tagName,
  value: ev,
  video_duration:
    e.id.includes("video") && (vplay === true || vstop === true)
      ? vd
      : undefined,
  video_current_time:
    e.id.includes("video") && (vplay === true || vstop === true)
      ? vct
      : undefined,
  video_percent:
    e.id.includes("video") && (vplay === true || vstop === true)
      ? vpct
      : undefined,
  video_status:
    e.id.includes("video") && (vplay === true || vstop === true)
      ? vs
      : undefined,
  video_provider:
    e.id.includes("video") && (vplay === true || vstop === true)
      ? vp
      : undefined,
  video_title:
    e.id.includes("video") && (vplay === true || vstop === true)
      ? vt
      : undefined,
  video_url:
    e.id.includes("video") && (vplay === true || vstop === true)
      ? vu
      : undefined,
  e_timestamp: tstamp, // milliseconds
  custom_timestamp: cstamp, // ISO 8601
  // user properties
  logged_in: logged,
  user_id: ui,
  user_profession: up,
});
utag.link()
utag.link({
  tealium_event: en || e.id,
  // event parameters
  button_text:
    e.tagName === "BUTTON" && e.innerText !== "" ? e.innerText : undefined,
  contact_method: cm,
  currency: cc,
  event_type: /generate_lead|form_submit/.test(en)
    ? "conversion"
    : "ui interaction",
  file_extension: e.id === "download" ? "pdf" : undefined,
  file_name: e.id === "download" ? "PDF_to_Download" : undefined,
  form_destination: fd,
  form_id: e.id.includes("form") ? e.id : undefined,
  form_name: e.id.includes("form") ? "User Profession Survey" : undefined,
  form_submit_text: e.id === "form" ? e.innerText : undefined,
  link_domain: ld,
  link_classes: lc,
  link_id: /extlink|intlink|download|banner/.test(e.id) ? e.id : undefined,
  link_url: lu,
  link_text: /extlink|intlink|download|banner/.test(e.id)
    ? e.innerText
    : undefined,
  method: e.id === "login" ? "Google" : undefined,
  outbound: ol,
  search_term: st,
  tag_name: e.tagName,
  value: ev,
  video_duration:
    e.id.includes("video") && (vplay === true || vstop === true)
      ? vd
      : undefined,
  video_current_time:
    e.id.includes("video") && (vplay === true || vstop === true)
      ? vct
      : undefined,
  video_percent:
    e.id.includes("video") && (vplay === true || vstop === true)
      ? vpct
      : undefined,
  video_status:
    e.id.includes("video") && (vplay === true || vstop === true)
      ? vs
      : undefined,
  video_provider:
    e.id.includes("video") && (vplay === true || vstop === true)
      ? vp
      : undefined,
  video_title:
    e.id.includes("video") && (vplay === true || vstop === true)
      ? vt
      : undefined,
  video_url:
    e.id.includes("video") && (vplay === true || vstop === true)
      ? vu
      : undefined,
  e_timestamp: tstamp, // milliseconds
  custom_timestamp: cstamp, // ISO 8601
  // user properties
  logged_in: logged,
  user_id: ui,
  custom_user_id: ui,
  user_profession: up,
});
amplitude.track()
amplitude.setUserId(ui);
amplitude.track({
  event_type: en || e.id,
  event_properties: {
    button_text: bt,
    contact_method: cm,
    currency: cc,
    event_type: /generate_lead|form_submit/i.test(en)
      ? "conversion"
      : "ui interaction",
    tag_name: e.tagName,
    file_extension: e.id === "download" ? "pdf" : undefined,
    file_name: e.id === "download" ? "PDF_to_Download" : undefined,
    form_destination: fd,
    form_id: e.id.includes("form") ? e.id : undefined,
    form_name: e.id.includes("form") ? "User Profession Survey" : undefined,
    form_submit_text: e.id === "form" ? fst : undefined,
    link_domain: ld,
    link_classes: lc,
    link_id: /extlink|intlink|download|banner/i.test(e.id) ? e.id : undefined,
    link_url: lu,
    link_text: /extlink|intlink|download|banner/i.test(e.id) ? bt : undefined,
    method: e.id === "login" ? "Google" : undefined,
    outbound: ol,
    search_term: st,
    value: ev,
    video_duration:
      e.id.includes("video") && (vplay === true || vstop === true)
        ? vd
        : undefined,
    video_current_time:
      e.id.includes("video") && (vplay === true || vstop === true)
        ? vct
        : undefined,
    video_percent:
      e.id.includes("video") && (vplay === true || vstop === true)
        ? vpct
        : undefined,
    video_status:
      e.id.includes("video") && (vplay === true || vstop === true)
        ? vs
        : undefined,
    video_provider:
      e.id.includes("video") && (vplay === true || vstop === true)
        ? vp
        : undefined,
    video_title:
      e.id.includes("video") && (vplay === true || vstop === true)
        ? vt
        : undefined,
    video_url:
      e.id.includes("video") && (vplay === true || vstop === true)
        ? vu
        : undefined,
    e_timestamp: tstamp, // milliseconds
    custom_timestamp: cstamp, // ISO 8601
  },
  user_properties: {
    $set: {
        logged_in: logged,
        custom_user_id: ui,
        user_profession: up,
    },
  },
});
mixpanel.track()
mixpanel.identify(ui);
mixpanel.people.set({
    logged_in: logged,
    custom_user_id: ui,
    user_profession: up,
});
mixpanel.track(en || e.id, {
    button_text: bt,
    contact_method: cm,
    currency: cc,
    event_type: /generate_lead|form_submit/i.test(en) ? 'conversion' : 'ui interaction',
    tag_name: e.tagName,
    file_extension: e.id === 'download' ? 'pdf' : undefined,
    file_name: e.id === 'download' ? 'PDF_to_Download' : undefined,
    form_destination: fd,
    form_id: e.id.includes('form') ? e.id : undefined,
    form_name: e.id.includes('form') ? 'User Profession Survey' : undefined,
    form_submit_text: e.id === 'form' ? fst : undefined,
    link_domain: ld,
    link_classes: lc,
    link_id: /extlink|intlink|download|banner/i.test(e.id) ? e.id : undefined,
    link_url: lu,
    link_text: /extlink|intlink|download|banner/i.test(e.id) ? bt : undefined,
    method: e.id === 'login' ? 'Google' : undefined,
    outbound: ol,
    search_term: st,
    value: ev,
    video_duration: e.id.includes('video') && (vplay === true || vstop === true) ? vd : undefined,
    video_current_time: e.id.includes('video') && (vplay === true || vstop === true) ? vct : undefined,
    video_percent: e.id.includes('video') && (vplay === true || vstop === true) ? vpct : undefined,
    video_status: e.id.includes('video') && (vplay === true || vstop === true) ? vs : undefined,
    video_provider: e.id.includes('video') && (vplay === true || vstop === true) ? vp : undefined,
    video_title: e.id.includes('video') && (vplay === true || vstop === true) ? vt : undefined,
    video_url: e.id.includes('video') && (vplay === true || vstop === true) ? vu : undefined,
    e_timestamp: tstamp, // milliseconds
    custom_timestamp: cstamp, // ISO 8601
});

Ecommerce Funnel Events

We have set up the ecommerce funnel events in way that collect information about the shopping behavior of the users. The approach for this was based on the [Google Measure Ecommerce|https://developers.google.com/analytics/devguides/collection/ga4/ecommerce?client_type=gtm] guide in the Google Analytics 4 documentation.

The items array-object

The following is an example of a collection of items, items array-object, that we are using in our implementation. The items array can include up to 200 elements.

const productList = [
  {
    item_name: "Stan and Friends Tee",
    affiliation: "Merchandise Store",
    item_brand: "MyCollection",
    item_category: "Apparel",
    item_category2: "Adult",
    item_category3: "Shirts",
    item_category4: "Crew",
    item_category5: "Short sleeve",
    item_list_id: "related_products",
    item_list_name: "Related Products",
    item_variant: "green",
    location_id: "ChIJIQBpAG2ahYAR_6128GcTUEo",
    price: 29.95,
  },
  {
    item_name: "Friends Pants",
    affiliation: "Merchandise Store",
    item_brand: "MyCollection",
    item_category: "Apparel",
    item_category2: "Adult",
    item_category3: "Pants",
    item_category4: "Crew",
    item_category5: "Regular Fit",
    item_list_id: "related_products",
    item_list_name: "Related Products",
    item_variant: "blue",
    location_id: "ChIJIQBpAG2ahYAR_6128GcTUEo",
    price: 39.95,
  },
  {
    item_name: "Canyonlands Full-Zip Hoodie",
    affiliation: "Merchandise Store",
    item_brand: "MyCollection",
    item_category: "Apparel",
    item_category2: "Adult",
    item_category3: "Jackets",
    item_category4: "Crew",
    item_category5: "Long sleeve",
    item_list_id: "related_products",
    item_list_name: "Related Products",
    item_variant: "black",
    location_id: "ChIJIQBpAG2ahYAR_6128GcTUEo",
    price: 99.0,
  },
];

When the user complete the ecommerce funnel by placing a purchase and firing the purchase event with one or more items defined with the relevant fields, the items array-object could look like this:

{
  items: [
    {
      item_id: "SKU_12345",
      item_name: "Canyonlands Full-Zip Hoodie",
      affiliation: "Merchandise Store",
      coupon: "SUMMER_FUN",
      discount: 9.9,
      index: 0,
      item_brand: "MyCollection",
      item_category: "Apparel",
      item_category2: "Adult",
      item_category3: "Jackets",
      item_category4: "Crew",
      item_category5: "Long sleeve",
      item_list_id: "related_products",
      item_list_name: "Related Products",
      item_variant: "black",
      location_id: "ChIJIQBpAG2ahYAR_6128GcTUEo",
      price: 99.0,
      quantity: 1,
    },
  ];
}

Clear the ecommerce object

It's recommended that we use the following command to clear the ecommerce object prior to pushing an ecommerce event to the data layer. Clearing the object will prevent multiple ecommerce events on a page from affecting each other. The ecommerce object clearance only applies to the GA4 data layer and Tealium data layer.

window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
  ecommerce: null,
}); // Clear the previous ecommerce object
utag.link({
  ecommerce: null,
}); // Clear the previous ecommerce object

Ecommerce events

For most of the ecommerce funnel events the implemented dataLayer array-object and utag.link data object is composed of:

window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
  event: en,
  // event parameters
  button_text: bt,
  event_type: et,
  tag_name: e.tagName,
  step: step.at(-1),
  ecommerce:
    en === "ecommerce_modal_closed" || en === "ecommerce_funnel_complete"
      ? undefined
      : {
          transaction_id: transactionID ?? undefined,
          value: itemsValue === 0 ? undefined : itemsValue.tofixed(2),
          tax: tax === 0 ? undefined : tax,
          shipping: shipping === 0 ? undefined : shipping,
          currency: itemsValue === 0 ? undefined : "USD",
          coupon: userCoupon ?? undefined,
          shipping_tier: userShipping ?? undefined,
          payment_type: userCCBrand ?? undefined,
          item_list_id: /productList/i.test(e.id)
            ? tempList[0].item_list_id
            : undefined,
          item_list_name: /productList/i.test(e.id)
            ? tempList[0].item_list_name
            : undefined,
          items: /productList/i.test(e.id) ? tempList : itemsSelected,
        },
  e_timestamp: tstamp, // milliseconds
  custom_timestamp: cstamp, // ISO 8601
  // user properties
  logged_in: logged,
  user_id: ui,
});

utag.link({
  tealium_event: en,
  // event parameters
  button_text: bt,
  event_type: et,
  tag_name: e.tagName,
  step: step.at(-1),
  ecommerce:
    en === "ecommerce_modal_closed" || en === "ecommerce_funnel_complete"
      ? undefined
      : {
          transaction_id: transactionID ?? undefined,
          value: itemsValue === 0 ? undefined : itemsValue.toFixed(2),
          tax: tax === 0 ? undefined : tax,
          shipping: shipping === 0 ? undefined : shipping,
          currency: itemsValue === 0 ? undefined : "USD",
          coupon: userCoupon ?? undefined,
          shipping_tier: userShipping ?? undefined,
          payment_type: userCCBrand ?? undefined,
          item_list_id: /productList/i.test(e.id)
            ? tempList[0].item_list_id
            : undefined,
          item_list_name: /productList/i.test(e.id)
            ? tempList[0].item_list_name
            : undefined,
          items: /productList/i.test(e.id) ? tempList : itemsSelected,
        },
  e_timestamp: tstamp, // milliseconds
  custom_timestamp: cstamp, // ISO 8601
  // user properties
  logged_in: logged,
  user_id: ui,
  custom_user_id: ui,
});

The Amplitude data object has similar composition in the object structure but the product item is send in a different way only when a purchase event or refund event occurs.

For the select item event the implemented dataLayer array-object and utag.link data object is composed of:

window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
  ecommerce: null,
}); // Clear the previous ecommerce object
utag.link({
  ecommerce: null,
}); // Clear the previous ecommerce object

window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
  event: "select_item",
  // event parameters
  button_text: el.id,
  section_heading: sh ?? undefined,
  event_type: "ui interaction",
  tag_name: el.tagName,
  step: step.at(-1),
  ecommerce: {
    item_list_id: itemsList[i].item_list_id,
    item_list_name: itemsList[i].item_list_name,
    items: itemsList[i],
  },
  e_timestamp: tstamp, // milliseconds
  custom_timestamp: cstamp, // ISO 8601
  // user properties
  logged_in: logged,
  user_id: ui,
});

utag.link({
  tealium_event: "select_item",
  // event parameters
  button_text: el.id,
  section_heading: sh ?? undefined,
  event_type: "ui interaction",
  tag_name: el.tagName,
  step: step.at(-1),
  ecommerce: {
    item_list_id: itemsList[i].item_list_id,
    item_list_name: itemsList[i].item_list_name,
    items: itemsList[i],
  },
  e_timestamp: tstamp, // milliseconds
  custom_timestamp: cstamp, // ISO 8601
  // user properties
  logged_in: logged,
  user_id: ui,
  custom_user_id: ui,
});

For the remove from cart event the implemented dataLayer array-object and utag.link data object is composed of:

window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
  ecommerce: null,
}); // Clear the previous ecommerce object
utag.link({
  ecommerce: null,
}); // Clear the previous ecommerce object

window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
  event: "remove_from_cart",
  // event parameters
  button_text: el.innerText,
  event_type: "ui interaction",
  tag_name: el.tagName,
  step: step.at(-1),
  alert_message: message,
  alert_impression: true,
  ecommerce: {
    currency: "USD",
    value: itemsSelected[ap].price,
    items: itemsSelected[ap],
  },
  e_timestamp: tstamp, // milliseconds
  custom_timestamp: cstamp, // ISO 8601
  // user properties
  logged_in: logged,
  user_id: ui,
});

utag.link({
  tealium_event: "remove_from_cart",
  // event parameters
  button_text: el.innerText,
  event_type: "ui interaction",
  tag_name: el.tagName,
  step: step.at(-1),
  alert_message: message,
  alert_impression: true,
  ecommerce: {
    currency: "USD",
    value: itemsSelected[ap].price,
    items: itemsSelected[ap],
  },
  e_timestamp: tstamp, // milliseconds
  custom_timestamp: cstamp, // ISO 8601
  // user properties
  logged_in: logged,
  user_id: ui,
  custom_user_id: ui,
});

Video Events

The video events use the general events dataLayer array-object and utag.link data object excluding the video progress event which use a unique dataLayer array-object and utag.link data object.

Using setInterval() function we implement the video progress event.

The implemented video progress event dataLayer array-object and utag.link data object is composed of:

window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
  event: en,
  event_type: "content tool",
  video_duration: vd,
  video_current_time: vct,
  video_percent: vpct,
  video_status: vs,
  video_provider: vp,
  video_title: vt,
  video_url: vu,
  e_timestamp: tstamp, // milliseconds
  custom_timestamp: cstamp, // ISO 8601
  // user properties
  logged_in: logged,
  user_id: ui,
});

utag.link({
  tealium_event: en,
  event_type: "content tool",
  video_duration: vd,
  video_current_time: vct,
  video_percent: vpct,
  video_status: vs,
  video_provider: vp,
  video_title: vt,
  video_url: vu,
  e_timestamp: tstamp, // milliseconds
  custom_timestamp: cstamp, // ISO 8601
  // user properties
  logged_in: logged,
  user_id: ui,
  custom_user_id: ui,
});

Error Events

The error events is a function that is called when errors occurs for Search event, Form event, Sing In event, and Sign Out event.

The implemented error events dataLayer array-object and utag.link data object is composed of:

window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
  event: `${en}_error`,
  event_type: "content tool",
  button_text: bt,
  section_heading: sh,
  tag_name: e.tagName,
  step: step.at(-1),
  error_message: m,
  alert_impression: true,
  e_timestamp: tstamp, // milliseconds
  custom_timestamp: cstamp, // ISO 8601
  // user properties
  logged_in: logged,
  user_id: ui,
});

utag.link({
  event: `${en}_error`,
  event_type: "content tool",
  button_text: bt,
  section_heading: sh,
  tag_name: e.tagName,
  step: step.at(-1),
  error_message: m,
  alert_impression: true,
  e_timestamp: tstamp, // milliseconds
  custom_timestamp: cstamp, // ISO 8601
  // user properties
  logged_in: logged,
  user_id: ui,
  custom_user_id: ui,
});

GTM Setup

The dataLayer array-object for the four main event has been setup in GTM comprised in four individual tags:

GTM Tags Screenshot

The set up for each tag and triggers is as follows:

General Events Tag

General Events Screenshot

Ecommerce Funnel Tag

Ecommerce Funnel Events Screenshot

Error Events Tag

Error Events Screenshot

Video Events Tag

Video Events Screenshot

Reference Documentation

=====

Copyright 2022-2024 | Arturo Santiago-Rivera | MIT License | Updated: January 24, 2024