Stuck with adding GA standard ecommerce transaction throught GTM - google-analytics

We use GTM to add GA to our website. Standard eCommerce tracking is enabled in GA. To start this project I am testing in our DEV environment which uses the same GTM/GA accounts. Only data from the live site shows up in GA so DEV is filtered out (I'm not sure how this is done yet). I have two problems.
How do I set up the 'transactionProducts' to loop through the items in the cart and display them separately instead of all smooshed together?
What do I do to see results in GA from the DEV site - I can't test this live - unless I create a noindex/nofollow static page on the live site with fake data to see if it will send it to GA.
I created the GTM eCommerce tag per GA directions:
Tag Type: Google Analytics: Universal Analytics
Track Type: Transaction
Google Analytics Settings: Enable overriding settings in this tag (we have a GA variable but I've decided to not use it incase it might interfere)
Tracking ID: UA-########-#
I created the GTM eCommerce trigger per GA directions:
Trigger Type: Page View (the DataLayer comes way after the GTM script)
This trigger fires on: Some Page Views
Fire this trigger...: Page URL contains /order/confirmation
The confirmation page is it's own page that comes after submit order page.
The DataLayer is thus:
<script>
if(window.location.pathname == "/order/confirmorder"){
// capture values from the spans with the following classes
var GAtransactionId = jQuery(".lblOrderNumber").text();
var GAtransactionTotal = jQuery(".lblTotal").text();
var GAtransactionTax = jQuery(".lblTax").text();
var GAtransactionShipping = jQuery(".lblShippingHandling").text();
// transactionProducts data from the spans with the following classes
var GAsku = jQuery(".lblProductSKU").text();
var GAname = jQuery(".lblProductSKU").text();
var GAprice = jQuery(".lblYourPrice").text();
var GAquantity = jQuery(".lblOrderItemQty").text();
// Checking my variables before they go thru
alert("GAtransactionId: " + GAtransactionId + " GAtransactionTotal: " + GAtransactionTotal + " GAtransactionTax: " + GAtransactionTax + " GAtransactionShipping: " + GAtransactionShipping + " GAsku: " + GAsku + " GAname: " + GAname + " GAprice: " + GAprice + " GAquantity: " + GAquantity);
window.dataLayer = window.dataLayer || [];
dataLayer.push({
'transactionId': GAtransactionId,
'transactionTotal': GAtransactionTotal,
'transactionTax': GAtransactionTax,
'transactionShipping': GAtransactionShipping,
'transactionProducts': [{
'sku': GAsku, // returns each item - but smooshed together
'name': GAname, // returns each item - but smooshed together
'price': GAprice, // returns each item - but smooshed together
'quantity': GAquantity // returns each item - but smooshed together
}]
});
}
</script>
In GTM Preview mode I do see the Current values of the Data Layer: but if I have more than one item in my cart the 'transactionProducts' items get all smooshed together.
transactionProducts: [
{
sku: 'ABCDEFGHIJK''
name: 'Blue CoatRed Coat',
price: '$30.99$31.99',
quantity: '11'
}
]
How do I loop through 'transactionProducts' to show each item in the cart separately? I guess a for loop might do but how would I set it up and then where would I add it to the DataLayer so it doesn't break anything? Also, do I need to remove the '$' sign from the result (I know how to do that)?
And where might I find a filter that prevents data from the DEV site from being sent through - so I can temporarily disable it while I test? And do I need to publish the GTM tag/trigger to have it actually send data or can I use Preview mode and expect to see DataLayer data in GA Conversions > Ecommerce > Overview?

you have to construct your items object looping through product elements in your cart instead of getting combined text value of all spans:
some sample code might look like:
var items = []
$('.some-product-selector').each(function () {
items.push({
'sku': $(this).find('.lblProductSKU').text(),
'price': $(this).find('.lblYourPrice').text()
// the same pattern for other fields
})
})
// ...
dataLayer.push({
'transactionId': GAtransactionId,
'transactionTotal': GAtransactionTotal,
'transactionTax': GAtransactionTax,
'transactionShipping': GAtransactionShipping,
'transactionProducts': items // use your items here
});

Related

Can I do multiple dataLayer pushes for a single transaction in Google Tag Manager?

I've set up tracking when a user completes a purchase. Right now, I'm doing multiple dataLayer pushes -- I do a push for the order total and then a seperate push for each product in the cart:
dataLayer.push({
'total': total
});
for(let i = 0; i < data.length; i++) {
const product = data[i];
dataLayer.push({
'name': product.name,
'price': product.price,
'quantity': product.quantity,
'sku': product.sku
});
}
Is this acceptable? I see in some examples the entire purchase being pushed as a single push (i.e. array of products). Does GTM behave the same in both cases?
You're not following the syntax. https://developers.google.com/tag-manager/enhanced-ecommerce#purchases the products are meant to be neatly stored within very specific structure. Not just pushed into the DL in hope that GTM would magically handle absence of strict structure.
Your example will not work.
GTM updates the internal state of variables only when you push a key called "event" to the datalayer. Your example does not have an "event" key, so GTM will not even noticed that you pushed something, at least until some other event happens later on.
Even if you added an event, your example would still not work as expected.
Since you push the product data with the keys name, price etc. to the top level of the datalayer, they will be overwritten with each new push (since you cannot have duplicate keys in the datalayer).
What you would do instead is add products to their own array within your loop, and then push the whole array to the datalayer:
var products = [];
for(i = 0; i < data.length; i++) {
const product = data[i];
products.push({
'name': product.name,
'price': product.price,
'quantity': product.quantity,
'sku': product.sku
});
};
dataLayer.push({
"products":products,
"event":"updateProductData"
});
If you want to use this for GA Enhances Ecommerce, it would be best to follow the advice from the other answer and construct your datalayer according to the specifications in the documentation.

Google analytics tag manager e-commerce dataLayer not sent

I am trying to send e-commerce events to google analytics using gtm (Google Analytics : Universal Analytics), this is my code
const loadGa = (next, retry) => {
if (!retry) retry = 0;
if (typeof ga === 'function') {
return next(null);
}
if (retry > 10) return next(new Error('Can not load google analytics'));
retry++;
setTimeout(() => loadGa(next, retry), 500);
}
const addProductGa = product => {
loadGa((err) => {
if (err) return console.error(err);
dataLayer.push({
event: 'addToCart',
ecommerce: {
currencyCode: 'EUR',
add: {
products: [{
name: product.name,
id: product.id,
price: product.acquisitionAmount / 100,
quantity: 1
}]
}
}
});
})
}
const purchaseGa = (charge, product) => {
loadGa((err) => {
if (err) return console.error(err);
dataLayer.push({
ecommerce: {
currencyCode: 'EUR',
purchase: {
actionField: {
id: charge.id,
revenue: charge.amount
},
products: [{
name: product.name,
id: product.id,
price: product.acquisitionAmount / 100,
quantity: 1
}]
}
}
});
})
}
For the example if I call the addProductGa
call to GTM
call to analytics
send basic tracking data
It seems that my e-commerce data are not sent, I can not see them in the network call to analytics server and I have no data on Google Analytics
What I can say:
By default dataLayer.push doesn't send data anywhere, it just feeds the dataLayer. You need GTM triggers and tags to send the data, which brings me to the next point
Missing event key in some of your dataLayer.push calls (eg purchase): I know you're following examples given in the GTM ecom spec but IMO it's confusing: some of them show an event-based collections (with the event key set), others pageview-based collection (without the event key set). To simplify your setup you should:
Always set the event key
Configure a trigger to handle those events
Full setup: once you have an event property on all your dataLayer calls, you can generically track them all using a setup similar to the one shown below (you should change the trigger to be a regex matching all your ecommerce events, also don't forget to enable Enhanced Ecommerce in the GA settings).
If the issue persists you should enable the GTM preview/debug which will tell you why certain tags aren't firing and will show you the debug of the dataLayer values it contains
If GTM confirms tags are firing but you don't see GA tracking on the network, you want to use the Chrome GA debugger which will show you in details what's happening and potentially why hits are not sent.
Don't forget to publish GTM once you have it all troubleshooted and working

Product view count tracking with Google Tag Manager and Google Analytics

In a symfony e-commerce project, to create a product view frequency report such that view count is increased when the user navigate to /product/detail/{id}. I am using Google Tag Manager and Analytics using the following as reference:
https://support.usabilla.com/hc/en-us/articles/360015738812-Integration-with-Google-Analytics-using-GTM-Data-Layer#
Google Tag Manager Setting
1. Create trigger
Trigger Type: Page View
Trigger Fire On: Some Page Views (Page path : contains : /products/detail)
2. Create variables
Name: dlv - productName
Variable Type: Data Layer Variable
Name: product.productName
Create Tag
Tag Type: Google Analytics: Universal Analytics
Track Type: Event
Category: Product Detail // static text
Action: View {{dlv - productName }}
Label: {{ dlv - productName }}
Value: {{ dlv - productName }}
Google Analytics Settings: {{ Google_Analytics_Track_ID_Settings }}
Tiggering: {{ Trigger_created_in_step_1 }}
Product Page
<script>
dataLayer.push({
'product': {
'productId': {{ Product.id }},
'productName': '{{ Product.name }}'
}
});
</script>
I can see dataLayer array is being sent to Google Tag Manager in the debug window. In Google Analytics > Behavior > Events > Top Events, I can see Product Detail in Event Category column. When I click the link the Event Action only shows View and Event Label is (not set). I want to create a tabular report like Product Detail: View Orange: 3, Product detail: View Apple: 4.
Cross-check that your {{ dlv - productName }} variable is properly populated and the value is available to the tag at the moment tag fires. If its value is populated later then the tag fires your event action would be tracked as (not set). If this is the case consider changing your trigger type to Window loaded or other event so the tag would grab the proper value from DL.
Although the key concept is provided in earlier answer, there are other solutions as well, which might give you better results.
So basically, you need to ensure, that the data you want to use from the dataLayer is available, when your tag is launched.
To achieve this, you can delay the tag to Window Loaded event, but you should be aware, that based on the size and content type of your page, a given percentage of your users will not have Window Loaded trigger launched, so you could miss part of your data. (They close the browser, navigate to other page before Window Loaded is reached.)
So an other option is to have the data pushed into the dataLayer before GTM is initialized. So your code looked something like this, placed above main GTM code in <head>:
<script>
var dataLayer = window.dataLayer || []; //define dataLayer, while avoiding overwriting its content
dataLayer.push({
'product': {
'productId': {{ Product.id }},
'productName': '{{ Product.name }}'
}
});
</script>
This way, your page view event will already see this data.
An other option would be to leave your code at it's current place, but to specify a triggering event, to let GTM know about the new data:
<script>
dataLayer.push({
'event': 'productDataReady',
'product': {
'productId': {{ Product.id }},
'productName': '{{ Product.name }}'
}
});
</script>
This way, you need to modify the trigger of your tag to be a Custom Event, matching the string used in the event variable. In this case, the data is available at this specific event.
Also, please note, that {{ dlv - productName }} should probably not used as event value, as Google Analytics accepts only integer values, while product name is likely to be a string.
An other consideration, is that you haven't specified (or at least haven't included it in your post), that the event should be non-interaction. If you generate an interactive event with your page load, assuming you also fire a pageview hit, you'll get an extremely low bounce rate.

Google Tag Manager access datalayer object values

I'm trying to access datalayer variables on add to cart event but it does not get tracked on the tag manager admin site
*The event is triggered but the values are not send
Datalayer push:
<script>
dataLayer.push({
'event': 'addToCart',
'ecommerce': {
'currencyCode': 'EUR',
'add': {
'products': [
{
'name': 'test',
'id': 'ZZZ232323',
'price': 33,
'brand': '',
'category': 'test',
'variant': '','quantity': 1
}
]
}
}
});
</script>
And i'm trying to access the datalayer to get the product name using:
dataLayer.find(x => x.event == 'addToCart').ecommerce.add.products[dataLayer.find(x => x.event == 'addToCart').ecommerce.add.products.length - 1].price
Image of google tag manager site
Data Layer Variables don't need to reference a specific step (array element) of the dataLayer. When you create a reference to a dataLayer variable, e.g. ecommerce, Google Tag Manager (GTM) will try to evaluate it at any given GTM event, but will fall back to undefined, or any other value, you specify.
This means, that if you fire your Facebook Pixel tracking code when the product data gets available (event = addToCart), a proper reference to the ecommerce data will have value in it. There are several options to get your product name.
You can create a general 'Ecommerce' variable, referencing ecommerce as Data Layer Variable Name. In your Facebook Pixel related code you will have to walk to the desired variable, and also take care for any possible missing values. However, this ecommerce variable can be used in several tags.
var productName = {{Ecommerce}}.add.products[0].name; //assuming you'll always have just one product in products array
Or, you can go for a specific variable, where your set 'Ecommerce - name of product added to cart', where you reference ecommerce.add.products[0].name. This way, you can simply assign this variable to the proper Facebook Pixel variable, using {{Ecommerce - name of product added to cart}}

redux-beacon: enhanced ecommerce actions not being fired

I'm using redux-beacon to manage google analytics enhanced ecommerce actions. What I'm noticing is that pageview events are being fired off fine but the enhanced ecommerce actions are not being sent. It's like they are being stored in the datalayer but no network request is being triggered. I'm new to enhanced ecommerce tracking so perhaps I'm missing something?
For example, here I have the events which are triggered when viewing a product:
export const analyticsEcommerceProduct = trackEcommProduct((action) => {
const { product } = action;
return {
id: product.id,
name: product.title,
category: product.type
};
}, CLIENT_TAG);
export const analyticsEcommerceAction = trackEcommAction((action) => {
const { actionType, id, revenue } = action;
return {
actionName: actionType,
id,
revenue
};
}, CLIENT_TAG);
Which are added to my eventMap:
const eventsMap = {
CLIENT_ANALYTICS_PAGEVIEW: clientPageView,
CLIENT_ANALYTICS_ECOMM_PRODUCT: analyticsEcommerceProduct,
CLIENT_ANALYTICS_ECOMM_ACTION: analyticsEcommerceAction
};
const middleware = createMiddleware(eventsMap, GoogleAnalytics(), GoogleTagManager());
Now when I land on the product page the analyticsEcommerceProduct and analyticsEcommerceAction events are firing as expected but no network request is made to send this information:
Is there some sort of event to 'send' the data that I need to add?
Is there some sort of event to 'send' the data that I need to add?
Yes, I believe so. In reading the examples that Google provides here: https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce, it looks like the eCommerce actions set meta data that will be sent along with the next event or pageview. Each example either ends with a ga('send', 'pageview'); or an event call like:
ga('send', 'event', 'Checkout', 'Option', {
hitCallback: function() {
// Advance to next page.
}
});
I'd try going to a new page and inspecting the call made there to see if it includes the data you need. If it does, I'll think of a way to make this easier for redux-beacon users. At the very least I think some documentation/tips are in order. As always, I'm open to suggestions/pr's.

Resources