How to get GA transaction info out of Salesforce B2B LWC and keep the same session - google-analytics

I am looking for a way to pass transaction data up from a LWC (lightning web component) to GA and not start a new session.
The primary issue is that the helper on the custom lighting web component is firing correctly, however when the ga(ecommerce, send) fires from within the LWC, it is setting a different clientID in the browswer.
If i try using ga(function(tracker) {var clientId = tracker.get('clientId');}); in the LWC it errors out as clientId is undefined.
I would like to be able to use the clientId instead of autolinker when calling
ga('create', trackingId, 'auto', { allowLinker: true });
ga('require', 'linker');
ga('require', 'ecommerce');
ga('linker:autoLink', [$A.get("$Label.c.Community_Site_URL")]);
there's two pushes going out. One is grand total via datalayer, the other is via ga add transaction
datalayer push
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({'transactionId ': order.Id,
'transactionAffiliation': order.SalesStore.Name,
'transactionTotal ': order.GrandTotalAmount,
'transactionShipping': order.TotalAdjustedDeliveryAmount,
'transactionTax': order.TotalTaxAmount
});
GA Add transaction
ga('ecommerce:addTransaction', {
'id': order.Id,
'affiliation': order.SalesStore.Name,
'revenue': order.GrandTotalAmount,
'shipping': order.TotalAdjustedDeliveryAmount,
'tax': order.TotalTaxAmount
});
orderItems.forEach(item => {
ga('ecommerce:addItem', {
'id': order.Id,
'name': item.orderItemInstance.zzzz.Name,
'sku': item.orderItemInstance.zzzz.StockKeepingUnit,
'price': item.orderItemInstance.TotalPrice,
'quantity': item.orderItemInstance.Quantity
});
});
ga('ecommerce:send');
This successfully fires to GA, and we can see the transactions. However, using the chrome extension, I can see that a new session has started for just the transaction event. So, for the main user session it will show the user visiting checkout and then order complete page, but no transaction info, while we see single page sessions for the transactions (and no campaign or adwords association).
is it possible to pass a value from the main window clientId to the LWC? that should allow us to link to the same session
Another solution mentioned passing data from the LWC to Aura. However, we already have the data going to GA. ("Whatever data you want to send to Google Analytics, send it from LWC to Aura through an event. And From Aura Component, fire a Google analytics event along with data received from LWC.") https://salesforce.stackexchange.com/questions/299303/google-analytics-event-tracking-in-community-using-lwc
this is a different use case as I just want the clientId and session to match
is there a GTM solution that will allow us to post to the main datalayer as opposed to how the datalayer push is working now?

Related

Google analytics 4 events sometimes not arriving

I am tracking purchases on a site in google analytics by sending a custom event from JavaScript to Google Tag Manager on the "successful purchase" page. Most of the time this works perfectly, but in some cases it seems the event just doesn't arrive to Google Analytics.
Initially I thought that maybe visiting the success page couldn't be relied on, but then I added an additional call after triggering the event that logs the sending of the event to my database. To my surprise, the events so far always get logged to my database, but they still sometimes don't show up in analytics. This is the code that does this:
const event = {
'event': 'purchase',
'ecommerce': {
'transaction_id': orderData.id,
'value': orderData.price,
'currency': 'EUR',
'coupon': orderData.CouponCode,
"items": orderData.services.map(elem => ({
'item_id': elem.id,
'item_name': elem.name,
'price': elem.price,
'item_type': elem.type,
'quantity': 1,
})),
}
};
// Send GA4 purchase event
dataLayer.push(event);
// Log to my db
fetch("/ajax/trackAnalytics", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
event,
cleaning_id: orderData.id
})
})
Let's take the 2nd of December as an example. According to google analytics these were the incoming purchases:
But in my database I received the following logs (I redacted the "items" field because it contained customer information but it shouldn't matter):
{
"event":"purchase",
"ecommerce":{
"transaction_id":6520,
"value":73.89,
"currency":"EUR",
"coupon":null
},
"timestamp":"2022-12-02T15:10:47+00:00"
}
{
"event":"purchase",
"ecommerce":{
"transaction_id":6519,
"value":67.99,
"currency":"EUR",
"coupon":null
},
"timestamp":"2022-12-02T15:57:44+00:00"
}
{
"event":"purchase",
"ecommerce":{
"transaction_id":6487,
"value":197.05,
"currency":"EUR",
"coupon":null
},
"timestamp":"2022-12-02T19:17:54+00:00"
}
As you can see, everything matches up except the transaction with ID 6520.
I tried creating orders that contained the exact elements 6520 did but I wasn't able to reproduce the issue that way. I also tried doing the same with a tracker blocker enabled on my browser but still the data came through.
The tag manager setup is the following:
Purchase trigger:
Purchase tag:
Sometimes if the user installed the ad block extension on their browser.
These kind of the analytic tags will not fire at all.
You said you tried installed some kind of this and it will work. This mean you might installed the different blocker as the user's.
Not every kind of blocker will block GA request. But still some of them did.
There are still many reasons cause the GA4 hit not sent. But if we are using the client side GTM container. It will always have some different with backend data. Just more or less.
As Darrellwan suggested, adding the line window.dataLayer = window.dataLayer || []; before dataLayer.push seems to have solved the problem, but it's not 100% clear.

Google Analytics Duplicate Transaction

I have an e-commerce site built on Nuxt.js and tracking set up in Google Tag Manager with Analytics. Whenever someone checks out, on the confirmation page I push to the dataLayer the checkout event (code below).
My problem is that sometimes the transaction is duplicated, sometimes the next day. The confirmation page cannot be reloaded or revisited and I get about 2 or 3 duplicates a week. I have seen creating custom tasks in analytics to prevent duplicate transactions but thought there has to be a simpler answer.
dataLayer.push({
'event': 'checkout',
'ecommerce': {
'checkout': {
'id': product.id,
'name': product.name,
'category': product.category,
'price': product.price.replace(/,/g, ""),
'quantity': 1
}
},
});
It seems that for some users the it was caching the ecommerce object and pushing on other events. To avoid this I just put the following code after pushing my purchase event:
dataLayer.push({ ecommerce: null });

Unable to see 'Transactions' section in Google Analytics

I have a production site in which my transactions are all recorded in google analytics correctly. Recently we have decided to create a staging environment which will be a replica of production. For this staging environment I created a new google account and hooked it up with Anaytics and Google tag manager. I then updated the code in staging environment to use this UA and GTM account ids.
When I look at my staging GA dashboard now, I see data, however I do not see a 'transactions' heading under 'ecommerce' and there is nowhere I can see my transactions. I have enabled 'ecommerce' for this GA dashboard from Account > Settings. Is there anything else I need to configure to see transactions in the dashboard?
Here is the official GTM dataLayer GA Enhanced Ecommerce spec:
https://developers.google.com/tag-manager/enhanced-ecommerce
Transactions are referred to as "purchase":
https://developers.google.com/tag-manager/enhanced-ecommerce#purchases
<script>
dataLayer.push({
'ecommerce': {
'purchase': {
'actionField': {
'id': 'T12345', // Transaction ID. Required for purchases and refunds.
'affiliation': 'Online Store',
'revenue': '35.43', // Total transaction value (incl. tax and shipping)
'tax':'4.90',
'shipping': '5.99',
'coupon': 'SUMMER_SALE'
},
'products': [{ // List of productFieldObjects.
'name': 'Triblend Android T-Shirt', // Name or ID is required.
'id': '12345',
'price': '15.25',
'brand': 'Google',
'category': 'Apparel',
'variant': 'Gray',
'quantity': 1,
'coupon': '' // Optional fields may be omitted or set to empty string.
},
...
The spec documentation isn't of the highest quality, so for a happy implementation I recommend the following best practices
dataLayer.push not working after GTM script
Always initialize the dataLayer
Always set the "event" property
To facilitate your life even more, you can do:
Event = ecommerce_{action}
Category = Ecommerce
Action = {action} (eg purchase, click...)
The event naming convention will allow you to create 1 single GTM trigger (Event REGEX ecommerce_.*) and therefore 1 single tag to capture all your Ecommerce events (having to create separate triggers/tags for each Ecommerce action is unnecessary and painful)
Once that's done, create a GTM Google Analytics Event tag with the above trigger, and enable Ecommerce in the GA settings:

How can I send custom dimensions with the product impressions event in Google Analytics?

I am currently trying to send custom dimension values with the product impressions event. Everything else seems to work but I am not able to report on the custom dimension values.
I have set up dimension8 and dimension 9 for star rating and review count. I have passed through these values to the object and it is successfully being sent.
dataLayer.push({
'event': 'productDetailImpressions',
'ecommerce': {
'detail': {
'actionField': {
'list': 'PDP'
},
'products': [{
'name': name,
'id': id,
'price': price,
'brand': brand,
'category': category,
'variant': variant,
'dimension8': reviewCount,
'dimension9': starRating
}]
}
}
});
I have set these custom dimensions up with product scope in GA.
I can view the tag and the information it is sending with a plugin in the browser, the values look correct.
However I am still not able to report on these values inside Google Analytics.
Is there anything I am doing wrong?
Thank you.
The scoping of dimensions required 2 things:
Configure scope in Google Analytics admin interface
See below screenshot:
Send custom dimension with the proper hit
Data is sent to Google Analytics with "hits". Hits are:
page tracking hits
event tracking hits
ecommerce tracking hits social
interaction hits
Now this doesn't mean that you should structure your dataLayer so that the custom dimensions are on the same level ase the object (eg user, product) you're trying to associate them with. Instead, you should follow the standard method for setting dimensions:
In Google Analytics, it is:
// Set the dimension
ga('set', 'cd1', 'Level 1');
// Send custom dimension along with a hit (eg pageview)
ga('send', 'pageview');
Now with Google Tag Manager, GTM doesn't send any hits to Google Analytics, it's just a tool for preparing your data and automating the use of GA. So an example on how to do it:
dataLayer.push({
'event': 'productDetailImpressions',
'dimension8': reviewCount,
'dimension9': starRating,
'ecommerce': {
'detail': {
'actionField': {
'list': 'PDP'
},
'products': [{
'name': name,
'id': id,
'price': price,
'brand': brand,
'category': category,
'variant': variant,
}]
}
}
});
Then create some dataLayer variables to read the custom dimension values:
Finally, assign those dimensions to your GA tags:
note: you could potentially make it work with the dataLayer you have, you would just have to replace your dataLayer variable to point to the right location, however I think it's bad practice because it leads to believe that dimensions have to be nested within the scoped object in order to work (which is not true) and it makes things harder to debug.

GTM ecommerce after container container code on page

I want to use GTM to track eCommerce transactions. This is a test for client environments where the code might be placed after the GTM code snippet which is why using Dom Ready as a trigger for the transaction tag is not reliable.
This is my test code:
<body>
<!-- Google Tag Manager -->
<script>window.dataLayer = window.dataLayer || [];</script>
<noscript><iframe src="//www.googletagmanager.com/ns.html?id=GTM-M4RNT2"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'//www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-XXXXXX');</script>
<!-- End Google Tag Manager -->
<div class="container">
<script>
window.dataLayer = window.dataLayer || []
dataLayer.push({
'transactionId': '32698',
'transactionAffiliation': 'Acme Clothing',
'transactionTotal': 38.26,
'transactionTax': 1.29,
'transactionShipping': 5,
'transactionProducts': [{
'sku': 'DD44',
'name': 'T-Shirt',
'category': 'Apparel',
'price': 11.99,
'quantity': 1
},{
'sku': 'AA1243544',
'name': 'Socks',
'category': 'Apparel',
'price': 9.99,
'quantity': 2
}]
});
</script>
</body>
As you can see the eCommerce code is taken straight from the Google documentation here.
I made sure that the pageview tag I'm firing works and I can see myself on the realtime view.
The issue is that no matter what I do to trigger the transaction tag, no eCommerce transactions are shown in Google Analytics.
Here is what I've tried:
Using 'event': 'eCommerce' right after the transaction products or in a separate script tag after the transaction code push and then using that event as a trigger
I've created a dataLayer variable in GTM that references transactionId and defaults it to false and then using event gtm.dom as a trigger with a filter for transactionId does not equal false
The frustrating part is that I have the GTM preview window open and it looks perfectly like it should work.
In attempt 1 above it shows a sequence of pageview, message, eCommerce DOM ready, page load where the dataLayer after message is correctly filled with transaction data and the eCommerce tag firing on the eCommerce event (i.e. data is in the dataLayer for sure.
In attempt 2 the dataLayer after Message is filled with transaction data and the eCommerce tag is fired on the DOM Ready event.
This has been going on for days now so it isn't a case of "the data hasn't shown up in GA yet". I am using the right UA tag since both tags reference the sasme onstant GTM variable and since I see myself in realtime the pageview tag uses the right UA and therefore so does the transaction tag. And yes eCommerce is obviously enabled in the view settings.
Simply pushing the transaction data to the data layer will not trigger the tracking to work. You need an action such as a pageview to pick up the transaction data and send it.
If you are unable to add the data layer before the GTM snippet, my recommendation would be the following:
Convert your code to be in the Enhanced Ecommerce format (provided below)
Add a custom event, in this case it is named trackTrans.
Add an event tag in GTM, labeled similar to Send Transaction. You can specify whatever values you'd like the for the event category/action/label.
In the event tag go to more settings > Ecommerce Features, enable Enable Enhanced Ecommerce Feature and Use data layer
Setting the trigger to be a Custom Event and specify trackTrans for the value
In your view settings make sure to enbable enhanced ecommerce tracking
dataLayer.push({
'ecommerce': {
'purchase': {
'actionField': {
'id': 'T12345', // Transaction ID. Required for purchases and refunds.
'affiliation': 'Online Store',
'revenue': '35.43', // Total transaction value (incl. tax and shipping)
'tax':'4.90',
'shipping': '5.99',
'coupon': 'SUMMER_SALE'
},
'products': [{ // List of productFieldObjects.
'name': 'Triblend Android T-Shirt', // Name or ID is required.
'id': '12345',
'price': '15.25',
'brand': 'Google',
'category': 'Apparel',
'variant': 'Gray',
'quantity': 1,
'coupon': ''
}]
}
},
'event' : 'trackTrans'
});
With what I have described above, the page will load then an event will fire and send the ecommerce transaction data with it.
As per your reference to the Google documentation, you need to
Place this code above the Google Tag Manager container snippet so that the data layer is ready when Google Tag Manager fires the Google Analytics tag asynchronously.
I have found a way to make it work. Ryan's answer was close but our experience with using event based triggers was spotty at best. I am now using the following setup that essentially guarantees transaction pickups by GTM unless the code is dynamically injected after page load via JS.
Here is how:
I created a dataLayer Variable which references transactionId and set its default to false
I created a trigger of type Custom Event, set the event to gtm.dom and a filter for the dataLayer variable I created to be not equal to false.
This ensures an actual transaction on the page overwrites the default value of false in that GTM variable and the gtm.dom trigger ensures that all code has loaded.
We have already tested this with clients on varying degrees of awfullness in terms of GTM implementations.

Resources