What would be the best way to register several options for a single checkout step with GA Enhanced ecommerce?
As the documentation describes:
// Called when user has completed shipping options.
function onShippingComplete(stepNumber, shippingOption) {
ga('ec:setAction', 'checkout_option', {
'step': stepNumber,
'option': shippingOption
});
ga('send', 'event', 'Checkout', 'Option', {
hitCallback: function() {
// Advance to next page.
}
});
}
The problem is that we collect the shipping and the payment option in one step, and we would like to track both selections. Here is our initial idea:
// Called when user has completed shipping and payment options.
function onStepComplete(stepNumber, shippingOption,paymentOption ) {
ga('ec:setAction', 'checkout_option', {
'step': stepNumber,
'option': shippingOption
});
ga('ec:setAction', 'checkout_option', {
'step': stepNumber,
'option': paymentOption
});
ga('send', 'event', 'Checkout', 'Option', {
hitCallback: function() {
// Advance to next page.
}
});
}
Would this work as expected? Could we afterwards segment correctly?
I'm afraid options are exclusive and they act as a dimension in the new enhanced checkout funnel reports from GA. If you want to analyse which shipping method works better, then you cannot mix it together with the payment method, both must be different dimensions since the values of a dimension are exclusive.
I would separate shipping and payment in two separate steps each one with their own dimension shipping/payment, even if you have a onestep checkout (quite normal nowadays) you can create as many steps as you want.
Take a look to the Enhanced Ecommerce Demo Store, here they are presenting the payment methods in the step 2 but when the user hits the selector in order to chose Visa/transfer/etc a step 3 is created.
Change the checkout_option to checkout - Seems to be the way Google handles the two separate types of events and what data is required for each to work in enhanced ecommerce. Just been facing the same issues myself and have managed to resolve with that fix.
Example based on your code would be:
// Called when user has completed shipping and payment options.
function onStepComplete(stepNumber, shippingOption,paymentOption ) {
ga('ec:setAction', 'checkout', {
'step': stepNumber,
'option': shippingOption
});
ga('ec:setAction', 'checkout', {
'step': stepNumber,
'option': paymentOption
});
ga('send', 'event', 'checkout', 'option', {
hitCallback: function() {
// Advance to next page.
}
});
}
each step allows only 1 dimension. The solution is to create sub-steps, and when you fire 2 sub-steps remember to send 2 events instead of 1, otherwise the last one will overwrite.
Here it is:
async.parallel([
function shippingOption(callback) {
ga('ec:setAction', 'checkout_option', {
'step': 1,
'option': shippingOption
});
ga('send', 'event', 'Checkout', 'Option', {
hitCallback: callback(null, true)
});
},
function paymentOption(callback) {
ga('ec:setAction', 'checkout_option', {
'step': 2,
'option': paymentOption
});
ga('send', 'event', 'Checkout', 'Option', {
hitCallback: callback(null, true)
})
}
], function(err, hitCallback){
// do something like going to next page
})
Related
I am using this code to handle the events on woocommerce remove from cart.
JS :
removeFromCartEventBind() {
document.body.addEventListener("click", (e) => {
const classList = e.target.className.split(" ");
const removeClasses = ["remove", "remove_from_cart_button"];
if (removeClasses.some((el) => classList.includes(el))) {
this.removeFromCart();
}
});
}
And I am calling the removeFromCart() function there.
removeFromCart() {
//Pushing data to tracker
console.log("Remove from Cart Called");
}
Are there any similar JS Events to track the other events like :
CartView, Checkout, Order, Search ..etc.
I'm implementing a Google Tag Manager data layer. Until now I have most of the Enhanced Ecommerce setup successfully.
When implementing the promotion view tag, I see in all the examples that I found a single tag being pushed with a list of all the promoFieldObjects. i.e.:
dataLayer.push({
'ecommerce': {
'promoView': {
'promotions': [ // Array of promoFieldObjects.
{
'id': 'JUNE_PROMO13', // ID or Name is required.
'name': 'June Sale',
'creative': 'banner1',
'position': 'slot1'
},
{
'id': 'FREE_SHIP13',
'name': 'Free Shipping Promo',
'creative': 'skyscraper1',
'position': 'slot2'
}]
}
}
});
Happens that in my application it is way easier to push the promotions in 4 different promotion view tags, since they are rendered in groups by several different decoupled react components.
So, my question is if there is any downside in splitting this tag in multiple instead of a single big one, like:
dataLayer.push({
'ecommerce': {
'promoView': {
'promotions': [
{
'id': 'JUNE_PROMO13',
'name': 'June Sale',
'creative': 'banner1',
'position': 'slot1'
}]
}
}
});
and
dataLayer.push({
'ecommerce': {
'promoView': {
'promotions': [
{
'id': 'FREE_SHIP13',
'name': 'Free Shipping Promo',
'creative': 'skyscraper1',
'position': 'slot2'
}]
}
}
});
When you split it, I think only the last one will be "seen" by GA. This is because the second push will overwrite the "promotions" property.
I think you can get around this by keeping track of the two promotions in an array and then do an overall push.
There is common JSPF var dataLayer = window.dataLayer = dataLayer || []; has declared.
On Checkout step -3
dataLayer.push({
'event' : 'checkout',
'ecommerce' : {
'currencyCode' : 'GBP',
'checkout' : {
'actionField' : {
'step' : 3,
'option' : '<some-value>',
'tax' : '<some-value>',
**'action' : 'checkout'**
},
'products' : '<some-value>'
}
}
});
It is working fine. Pushing correct data.
On Checkout step - 4
dataLayer.push({
'event' : 'checkout',
'ecommerce' : {
'currencyCode' : 'GBP',
'checkout' : {
'actionField' : {
'step' : 4,
'option' : '<some-value>',
'tax' : '<some-value>',
**'action' : 'purchase'**
},
'products' : '<some-value>'
}
}
});
It still pushing 'checkout' not 'purchase'. The datalayer pushing of elements from same file for step-3 and step-4. And declaration is from .JSPf which is included in it. It seems like 'action' element is cached.I had tried with cleaning browser history but no success.
Please tell where i had lacked.
The actionField.action field is automatically populated by GTM/Universal Analytics. You should never manually add a value to it.
The field value is derived from the property name that wraps actionField and products. Thus if the hit is a "Checkout" hit, the property key would be checkout, and if the hit is a "Purchase" hit, the property key would be purchase.
Example Checkout hit for step 4:
event: 'checkout',
ecommerce: {
checkout: {
actionField: {
step: 4,
option: 'some-option'
}
}
}
Example Purchase hit:
event: 'purchase',
ecommerce: {
currencyCode: 'GBP',
purchase: {
actionField: {
id: 'some-transaction-id',
revenue: 'some-transaction-revenue',
tax: 'some-transaction-tax',
shipping: 'some-transaction-shipping'
},
products: [{
...products in the purchase...
}]
}
}
I want to load all the links to my pages. What I did it, created a seperate subscription with only the slug and title fields. Used this data in my navigation and it worked. But now I need to subscribe on every single page with all the fields. The problem is, it's showing only the slug and title fields. I think the two subscriptions are conflicting. Here's my subscriptions :
Meteor.publish("pageLinks", function() {
return Pages.find({}, {
fields: {
title: 1,
slug: 1
}
});
});
Meteor.publish("page", function(slug) {
check(slug, String);
return Pages.findOne({
slug: slug
});
});
And my subscriptions in the route for the single page :
FlowRouter.route('/page/:slug', {
name: 'pageSingle',
subscriptions: function(params, queryParams) {
this.register('page', Meteor.subscribe('page', params.slug));
},
action() {
BlazeLayout.render('panelLayout', {
content: 'pageSingle'
});
setTitle('Page');
}
});
For the links, I subscribed in the template like this :
Template.panelLinks.onCreated(function() {
this.autorun(function() {
Meteor.subscribe('pageLinks');
});
});
Template.panelLinks.helpers({
pageLinks: function() {
return Pages.find({});
}
});
Here's how I display the links :
{{#each pageLinks}}
{{> pageLink}}
{{/each}}
What is the best way to solve this conflict and load all the fields of a page only in that page's route?
First, there is mistake in your publish function:
Meteor.publish("page", function(slug) {
check(slug, String);
return Pages.findOne({
slug: slug
});
});
You should see in console error :
Error: Publish function can only return a Cursor or an array of Cursors
Replace Pages.findOne with Pages.find
If you correct mistake then you should be able to use different subscriptions of the same collection (Pages) and receive correct data.
When customers place orders on our system, they can be buying from one of several different "stores". We have a consolidated Shopping Cart experience, but split the transaction into individual orders as the final step.
I need some way to, on the final "thank you" page of the check out funnel, add products and record a transaction multiple times.
Does setting an action of "purchase" effectively clear the products so I can add more and repeat the process? For example...
ga('ec:addProduct', { 'id': '1' });
ga('ec:addProduct', { 'id': '2' });
ga('ec:setAction', 'purchase', { 'id': '123456' });
ga('ec:addProduct', { 'id': '3' });
ga('ec:setAction', 'purchase', { 'id': '987654' });
...In the above scenario, will Transaction 123456 contain products 1 & 2, while Transaction 987654 contains only product 3? Or, will Transaction 987654 contain products 1, 2, & 3?
Appreciate any insight into this!
Best,
Nate
You have to split the transactions by sending an event between them, this hit will send all the information so you can start over with the next transaction.
ga('ec:addProduct', { 'id': '1' });
ga('ec:addProduct', { 'id': '2' });
ga('ec:setAction', 'purchase', { 'id': '123456' });
ga('send','event','whatever',{'non-interaction': 1});
ga('ec:addProduct', { 'id': '3' });
ga('ec:setAction', 'purchase', { 'id': '987654' });
ga('send','event','whatever',{'non-interaction': 1});