Skip to content

Commit 4b6a709

Browse files
initial commit
1 parent c80f8cd commit 4b6a709

File tree

2 files changed

+517
-0
lines changed

2 files changed

+517
-0
lines changed

FlowDataLayer.js

+267
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,267 @@
1+
/* global ga, Flow, ShopifyAnalytics */
2+
/* eslint-disable no-var, prefer-arrow-callback, prefer-template, object-shorthand */
3+
4+
(function flowDL() {
5+
6+
// dependencies
7+
// cookie handling
8+
function setCookie(cname,cvalue,exdays){var d=new Date();d.setTime(d.getTime()+(exdays*24*60*60*1000));var expires="expires="+d.toUTCString();document.cookie=cname+"="+cvalue+";"+expires+";path=/"}function getCookie(cname){var name=cname+"=";var decodedCookie=decodeURIComponent(document.cookie);var ca=decodedCookie.split(';');for(var i=0;i<ca.length;i++){var c=ca[i];while(c.charAt(0)==' '){c=c.substring(1)}if(c.indexOf(name)==0){return c.substring(name.length,c.length)}}return""};
9+
10+
var NOT_SET = '(not set)';
11+
12+
function gaReady() {
13+
return typeof ga !== 'undefined';
14+
}
15+
16+
// Flow is ready of 'getExperience' function exists
17+
function flowReady() {
18+
return Flow && typeof Flow.getExperience === 'function';
19+
}
20+
21+
// Wait until trekkie is loaded (lib will transition from an empty array to an object).
22+
function shopifyAnalyticsReady() {
23+
return ShopifyAnalytics && typeof ShopifyAnalytics.lib === 'object';
24+
}
25+
26+
function isReady() {
27+
return gaReady() && flowReady() && shopifyAnalyticsReady();
28+
}
29+
30+
/**
31+
* Exponential backoff. Keep trying but delay a little longer each attempt.
32+
*/
33+
function backoff(test, callback, delay) {
34+
function getNewDelay() {
35+
if (!delay) {
36+
return 1;
37+
}
38+
39+
return (delay >= Number.MAX_VALUE) ? delay : delay * 2;
40+
}
41+
42+
if (test()) {
43+
callback();
44+
} else {
45+
setTimeout(function () {
46+
backoff(test, callback, getNewDelay());
47+
}, Math.log(getNewDelay()) * 100);
48+
}
49+
}
50+
51+
function getItemFromCart(id, cart) {
52+
var len = cart.items.length;
53+
var item;
54+
var i = 0;
55+
56+
for (i = 0; i < len; i += 1) {
57+
if (id.toString() === cart.items[i].variant_id.toString()) {
58+
item = cart.items[i];
59+
}
60+
}
61+
62+
return item;
63+
}
64+
65+
function getOrderPricing(order) {
66+
var pricing = {};
67+
var prices = order.prices;
68+
var pricesLength = order.prices.length;
69+
var i;
70+
71+
for (i = 0; i < pricesLength; i += 1) {
72+
pricing[prices[i].key] = prices[i].base.amount;
73+
}
74+
75+
return pricing;
76+
}
77+
78+
function setupAddToCart() {
79+
Flow.on('cart.addItem', function (data) {
80+
81+
// clear any existing shopify cart items to prevent generic DL cart from being fired
82+
if($.cookie('clearCart') === undefined){
83+
$.removeCookie('cart', {path: '/'});
84+
$.cookie('clearCart','1');
85+
}
86+
87+
var item = getItemFromCart(data.id, data.cart);
88+
var eventData = {
89+
'products': [{
90+
'variant': item.variant_id,
91+
'id': item.product_id,
92+
'quantity': data.quantity,
93+
'price': item.local.price.base.amount,
94+
'name': item.title,
95+
'sku': item.sku,
96+
}],
97+
};
98+
99+
// push to dataLayer
100+
dataLayer.push(eventData,{
101+
'pageType' : 'Add to Cart',
102+
'event' : 'Add to Cart'
103+
});
104+
if(__bva__.debug){
105+
console.log("Add to Cart"+" :"+JSON.stringify(eventData, null, " "));
106+
}
107+
});
108+
}
109+
110+
function setupViewCart() {
111+
// cart pageview
112+
Flow.on('pageview.cart', function (data) {
113+
114+
// clear any existing shopify cart items to prevent generic DL cart from being fired
115+
if(getCookie('clearCart') === "undefined"){
116+
document.cookie = "cart=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
117+
setCookie('clearCart','1',0);
118+
}
119+
120+
var item = data.cart;
121+
testget = item;
122+
var eventData = {
123+
'products': [{
124+
'variant': item.variant_id,
125+
'id': item.product_id,
126+
'quantity': data.quantity,
127+
'price': item.local.price.base.amount,
128+
'name': item.title,
129+
'sku': item.sku,
130+
}],
131+
};
132+
133+
// push to dataLayer
134+
dataLayer.push(eventData,{
135+
'pageType' : 'Cart',
136+
'event' : 'Cart'
137+
});
138+
if(__bva__.debug){
139+
console.log("Cart"+" :"+JSON.stringify(eventData, null, " "));
140+
}
141+
142+
});
143+
}
144+
145+
function gaAddProducs(order) {
146+
var lines = order.lines;
147+
var linesLength = lines.length;
148+
var i;
149+
150+
for (i = 0; i < linesLength; i += 1) {
151+
ga('ec:addProduct', {
152+
id: lines[i].shopify.product_id,
153+
name: lines[i].shopify.title,
154+
variant: lines[i].shopify.variant_id,
155+
price: lines[i].price.base.amount,
156+
quantity: lines[i].shopify.quantity,
157+
});
158+
}
159+
}
160+
161+
// GA Funnel Step 1 - Cart
162+
function gaStep1() {
163+
ga('ec:setAction', 'checkout', {
164+
step: 1,
165+
});
166+
167+
}
168+
169+
// GA Funnel Step 2 - Login
170+
function gaStep2() {
171+
ga('ec:setAction', 'checkout', {
172+
step: 2,
173+
});
174+
175+
}
176+
177+
// GA Funnel Step 3 - Checkout: Customer Information
178+
function gaStep3(order) {
179+
gaAddProducs(order);
180+
ga('ec:setAction', 'checkout', {
181+
step: 3,
182+
});
183+
gaDimensions();
184+
185+
}
186+
187+
// GA Funnel Step 4 - Checkout: Shipping Information
188+
function gaStep4(order) {
189+
gaAddProducs(order);
190+
ga('ec:setAction', 'checkout', {
191+
step: 4,
192+
});
193+
gaDimensions();
194+
195+
}
196+
197+
// GA Funnel Step 5 - Checkout: Shipping Information
198+
function gaStep5(order) {
199+
gaAddProducs(order);
200+
ga('ec:setAction', 'checkout', {
201+
step: 5,
202+
});
203+
gaDimensions();
204+
205+
}
206+
207+
// GA Funnel Step 6 - Checkout: Thank You
208+
function gaPurchase(order) {
209+
var orderPricing = getOrderPricing(order);
210+
211+
gaAddProducs(order);
212+
ga('ec:setAction', 'purchase', {
213+
id: order.number,
214+
revenue: order.total.base.amount,
215+
tax: orderPricing.tax || 0,
216+
shipping: getOrderPricing.shipping || 0,
217+
});
218+
gaDimensions();
219+
ga('send', 'event', 'Flow Checkout', 'Thank You');
220+
ga('send', 'event', 'Flow Checkout', 'Purchase');
221+
}
222+
223+
function setupCheckoutStep1() {
224+
Flow.set('on', 'pageview.checkout_step_1', function (data) {
225+
gaStep1();
226+
gaStep2();
227+
gaStep3(data.order);
228+
});
229+
}
230+
231+
function setupCheckoutStep2() {
232+
Flow.set('on', 'pageview.checkout_step_2', function (data) {
233+
gaStep4(data.order);
234+
});
235+
}
236+
237+
function setupCheckoutStep3() {
238+
Flow.set('on', 'pageview.checkout_step_3', function (data) {
239+
gaStep5(data.order);
240+
});
241+
}
242+
243+
function setupCheckoutThankYou() {
244+
Flow.set('on', 'pageview.checkout_thank_you', function (data) {
245+
gaPurchase(data.order);
246+
});
247+
}
248+
249+
function setup() {
250+
console.log('[flow_ga] Setup!');
251+
252+
// allPages();
253+
setupAddToCart();
254+
setupViewCart();
255+
setupCheckoutStep1();
256+
setupCheckoutStep2();
257+
setupCheckoutStep3();
258+
setupCheckoutThankYou();
259+
}
260+
261+
function init() {
262+
// Wait for GA, Shopify and Flow to be ready.
263+
backoff(isReady, setup);
264+
}
265+
266+
init();
267+
}());

0 commit comments

Comments
 (0)