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