# Integrating your Analytics

## **Use Case**

You’d like to integrate your own analytics pipeline (e.g. Google Analytics) with Jane.

### **High-Level Solution**

When users interact on your menu, Jane’s embedded solution will dispatch an ‘analytics event’ using the browser’s [postMessage API](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage). You can listen to these events and fire off any analytics events you wish.

### **Supported Events:**

Glossary

```javascript
product_id = number // the ID of the product
name = string // the name of the product
brand = string // the brand of the product
category = ["indica", "sativa", "hybrid", "cbd"]
kind = ["flower", "edible", "extract", "merch", "grow", "tincture", "gear", "topical", "pre-roll", "vape"]

// Checkout Event Data
count = number // the quantity added to cart of each item
unit_price = number // the unit price of each item
special_id = number | null // if applicable, the id of the special applied to the product
special_title = string | null // if applicable, the title of the special applied to the product
```

[Checkout](https://developers.google.com/analytics/devguides/collection/ga4/reference/events?client_type=gtag#purchase)

```javascript
{ messageType: 'analyticsEvent',  
  payload: { name : 'checkout',  
             properties: {
                brandIds: string,
                brandNames: string,
                cartId: number,
                customerBirthDate: string,
                customerEmail: string,
                customerFirstName: string,
                customerLastName: string,
                customerPhone: string,
                deliveryAddress: {
                  city: string,
                  country_code: string,
                  lat: number,
                  lng: number
                  state_code: string,
                  street: string,
                  zipcode: string,
                },
                deliveryFee: number,
                deliveryWindowEndTime: string,
                deliveryWindowStartTime: string,
                discountTotal: number,
                estimatedTotal: number,
                paymentMethod: string,
                preDiscountSubtotal: number,
                products: Array { 
                   brand: string,
                   category: string,
                   count: number,
                   kind: string,
                   name: string,
                   price_id: string,
                   product_id: number,
                   special_id: number,
                   special_title: string,
                   unit_price: number
                },
                reservationMode: string,
                salesTax: number,
                serviceFee: number,
                storeId: number,
                storeNotes: string,
                storeTax: number,
                tags: {key: string, key: string ...}
                uuid: string  
             }  
           }
}
```

Menu Load&#x20;

*`customerEmail` will be non-null only if the user is authenticated.*

```javascript
{ messageType: 'analyticsEvent',  
  payload: { name : 'menuLoad',  
             properties: { storeId: string }  
           }
}
```

[Product View](https://developers.google.com/analytics/devguides/collection/ga4/reference/events?client_type=gtag#view_item)

```javascript
{ messageType: 'analyticsEvent',  
  payload: { name : 'productView',  
             properties: { 
               productId: string, 
               productKind: string 
               product: { category, brand, name, kind } 
             }    
           }
}
```

[Item Added To Cart](https://developers.google.com/analytics/devguides/collection/ga4/reference/events?client_type=gtag#add_to_cart)

```javascript
{ messageType: 'analyticsEvent',  
  payload: { name : 'cartItemAdd',  
             properties: { 
               productId: string,
               product: { product_id, name, brand, category, kind }
             }  
           }
}
```

[Item Removed From Cart](https://developers.google.com/analytics/devguides/collection/ga4/reference/events?client_type=gtag#remove_from_cart)

```javascript
{ messageType: 'analyticsEvent',  
  payload: { name : 'cartItemRemoval',  
             properties: { productId: string }  
           }
}
```

Quantity of item changes

```javascript
{ messageType: 'analyticsEvent',
  payload: { name : cartItemChangeCount',
             properties: { productId: string, count: number }
  }
}
```

**Pre-requisite:**

To be able to properly send the data to Google Analytics, the Google Tag has to be properly installed in your site. This can be done either automatically via [Google Tag Manager](https://tagmanager.google.com/#/home) or manually, as shown in the tagging instructions sections of the setup.&#x20;

The manual installation boils down to adding the script shown below, adding the proper id of your Google Analytics&#x20;

```html

<script async src="https://www.googletagmanager.com/gtag/js?id=YOUR_ID"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag() {
    dataLayer.push(arguments);
  }
  gtag("js", new Date());

  gtag("config", "YOUR_ID");
</script>
```

**Implementation:**

```javascript
<script>
     window.addEventListener("message", receiveMessage, false);

      function receiveMessage(event) {
        var payload = event.data && event.data.payload;

        if (!payload || event.data.messageType !== 'analyticsEvent') return;

        if (
          payload.name === "checkout"
        ) {
            var subtotal = 
              payload.properties && payload.properties.estimatedTotal;
            var storeId = payload.properties && payload.properties.storeId;
            var cartId =
              payload.properties && payload.properties.cartId;
            var products =
              payload.properties && payload.properties.products;
  
            // Do something with payload          
            console.log(subtotal, cartId, products);
            
            // Can use storeId to set affiliation in case of multiple stores
            // Eg:
            // let storeName = "default value";
            // if (storeId === 1) {
            //    storeName = "Store 1 name";
            // }
            
            // Example – if you're using Enhanced Ecommerce in Google Analytics, 
            // you can use the following code:
            var items = products.map(
            ({
              product_id,
              name,
              brand,
              category,
              kind,
              unit_price,
              count,
              special_id,
              special_title,
            }) => ({
              item_id: product_id,
              item_name: name,
              item_brand: brand,
              item_category: kind,
              item_variant: category,
              quantity: count,
              price: unit_price,
              affiliation: "store",
            })
          );
          
          gtag("event", "purchase", {
            transaction_id: cartId,
            value: subtotal,
            currency: "USD",
            items: items,
          });
        }
        
        if (
          payload.name === 'menuLoad' 
        ) {
           var storeId =
             payload.properties && payload.properties.storeId;
             
           // Do something with the customerEmail if user is authenticated
           console.log(storeId);
        }

        if (
          payload.name === 'productView' 
        ) {
           var productId = 
             payload.properties && payload.properties.productId;
           var productKind = 
             payload.properties && payload.properties.productKind;
           var product = 
             payload.properties && payload.properties.product;
             
           // Do something with productId, productKind, product
           console.log(productId, productKind, product);
           
           // Sample call with minimum fields so GA can receive the data
           gtag('event', 'view_item', {
              value: 1,
              currency: 'USD',
              items: [{ item_id: productId , item_name: product.name}],
           });
        }

        if (
          payload.name === 'cartItemAdd' 
        ) {
           var productId = 
             payload.properties && payload.properties.productId;
           var product = 
             payload.properties && payload.properties.product;

          // Do something with the productId
          console.log(productId); 
            
         // Sample call with minimum fields so GA can receive the data
          gtag('event', 'add_to_cart', {
             value: 1,
             currency: 'USD',
             items: [{ item_id: productId , item_name: product.name}],
          });
        }

        if (
          payload.name === 'cartItemRemoval' 
        ) {
           var productId = 
             payload.properties && payload.properties.productId;
             
           // Do something with the productId
           console.log(productId); 
           
           // Sample call with minimum fields so GA can receive the data
           gtag('event', 'remove_to_cart', {
             value: 1,
             currency: 'USD',
             items: [{ item_id: productId , item_name: productId}],
           });
        }
      }
    </script>
```

**Disclaimer:** \
Google requires specific fields for some events that we currently don't have accessible. We are working on exposing them to the scripts, meanwhile we have to use dummy data so the events are valid.

### Jane Boost: UTM Tracking with Google Tag Manager

Boost is a single-page app, which means that the URL changes (without doing a page load) as the user navigates the site. The URL changing is what allows us to get SEO benefits from Boost. This is different from before, because when you load Jane in an iFrame, the URL stays the same. The first time that the URL typically changes is when the user goes to the checkout page.

With respect to GA, it sets a parameter called Document Location (dl) when the Google Analytics object is instantiated. This parameter contains the full page URL (including any UTMs), and Google extracts UTMs from this. For our own first-party GA integration, we create this object once and then continue to send events with the same instance. This means that UTMs are preserved in our events.

The issue is that when you use GTM and the data layer, which it appears you do with your custom analytics script. GTM creates a new Google Analytics instance for each request, so Document Location will be set differently each call. For earlier calls, it will be set to the regular value, but when you get to the cart, it won't contain the UTM params.

There are two possible solutions for this:

1. You can get GTM to use a single instance of GA (this should be an easy fix, but has some risks depending on your setup)
2. You can send the initial url as a variable to the data layer, and then modify your logging code a little bit to have this set as location.

\
Both solution are detailed further [in this article](https://www.simoahava.com/gtm-tips/fix-rogue-referral-problem-single-page-sites/)

### Boost 4 All GTM setup

To setup GTM for Boost 4 All, you will need to grab the script that Google gives from their intallation steps and add it to the page template you selected for your Boost menu. If you already have a menu up, you can add that script directly to the imported template on your Business dashboard Boost menu configuration.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.iheartjane.com/jane-docs/embeds/integrating-your-analytics.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
