@elevateab/sdk 1.2.0 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +365 -101
- package/dist/ElevateAnalytics-Cp5iR7dJ.d.cts +48 -0
- package/dist/ElevateAnalytics-Cp5iR7dJ.d.ts +48 -0
- package/dist/cartAttributes-4XA3JSEP.js +2 -0
- package/dist/cartAttributes-4XA3JSEP.js.map +1 -0
- package/dist/cartAttributes-NW2TWOYC.js +3 -0
- package/dist/cartAttributes-NW2TWOYC.js.map +1 -0
- package/dist/chunk-4D5I75NE.js +19 -0
- package/dist/chunk-4D5I75NE.js.map +1 -0
- package/dist/chunk-VUGOZ5MR.js +18 -0
- package/dist/chunk-VUGOZ5MR.js.map +1 -0
- package/dist/chunk-XXNIBCJ6.js +2 -0
- package/dist/chunk-XXNIBCJ6.js.map +1 -0
- package/dist/hydrogen.cjs +18 -0
- package/dist/hydrogen.cjs.map +1 -0
- package/dist/hydrogen.d.cts +48 -0
- package/dist/hydrogen.d.ts +48 -0
- package/dist/hydrogen.js +2 -0
- package/dist/hydrogen.js.map +1 -0
- package/dist/index.cjs +40 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1433 -33
- package/dist/index.d.ts +1433 -33
- package/dist/index.js +24 -1
- package/dist/index.js.map +1 -1
- package/dist/next.cjs +42 -0
- package/dist/next.cjs.map +1 -0
- package/dist/next.d.cts +734 -0
- package/dist/next.d.ts +734 -0
- package/dist/next.js +26 -0
- package/dist/next.js.map +1 -0
- package/package.json +31 -4
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
export { a as ElevateAnalytics, E as ElevateHydrogenAnalyticsProps, U as UseAnalyticsHook } from './ElevateAnalytics-Cp5iR7dJ.js';
|
|
2
3
|
|
|
3
4
|
interface BackendConfig {
|
|
4
5
|
allTests: {
|
|
@@ -7,33 +8,89 @@ interface BackendConfig {
|
|
|
7
8
|
selectors?: {
|
|
8
9
|
selectorsV2?: unknown[];
|
|
9
10
|
};
|
|
11
|
+
/**
|
|
12
|
+
* Indicates if the subscription is paused/stopped.
|
|
13
|
+
* When true, SDK should not initialize and just render children.
|
|
14
|
+
*/
|
|
15
|
+
subscriptionPaused?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Human-readable message about subscription status.
|
|
18
|
+
*/
|
|
19
|
+
subscriptionMessage?: string;
|
|
10
20
|
}
|
|
11
|
-
interface
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
interface BackendTestData {
|
|
22
|
+
name: string;
|
|
23
|
+
isLive: boolean;
|
|
24
|
+
settings?: Record<string, unknown>;
|
|
25
|
+
type: string;
|
|
26
|
+
filters?: unknown[];
|
|
27
|
+
isPersonalization?: boolean;
|
|
28
|
+
testTrafficPercentage?: number;
|
|
29
|
+
handles?: string[];
|
|
30
|
+
productIds?: string[];
|
|
31
|
+
defaultVariants?: Record<string, string>;
|
|
32
|
+
currencies?: string[];
|
|
33
|
+
links?: string[];
|
|
34
|
+
pathnames?: string[];
|
|
35
|
+
excludePathnames?: string[];
|
|
36
|
+
redirectBehavior?: string;
|
|
37
|
+
variantIds?: string[];
|
|
38
|
+
options?: string[];
|
|
39
|
+
shippingZones?: {
|
|
40
|
+
countriesToInclude?: string[];
|
|
41
|
+
countriesToExclude?: string[];
|
|
23
42
|
};
|
|
24
|
-
|
|
43
|
+
}
|
|
44
|
+
interface BackendTest {
|
|
45
|
+
data: BackendTestData;
|
|
46
|
+
[variationId: string]: BackendVariation | BackendTestData;
|
|
25
47
|
}
|
|
26
48
|
interface BackendVariation {
|
|
27
49
|
variationName: string;
|
|
28
50
|
trafficPercentage: number;
|
|
29
51
|
isDone?: boolean;
|
|
30
52
|
isControl?: boolean;
|
|
31
|
-
id?:
|
|
53
|
+
id?: string;
|
|
32
54
|
productTitle?: string;
|
|
33
55
|
handle?: string;
|
|
34
56
|
price?: string;
|
|
35
57
|
link?: string;
|
|
36
58
|
productVariants?: unknown[];
|
|
59
|
+
originalProductHandle?: string;
|
|
60
|
+
prices?: Record<string, {
|
|
61
|
+
main: string;
|
|
62
|
+
price: Record<string, string>;
|
|
63
|
+
compare: Record<string, string | null>;
|
|
64
|
+
}>;
|
|
65
|
+
images?: Array<{
|
|
66
|
+
productId: string;
|
|
67
|
+
handle: string;
|
|
68
|
+
index: number;
|
|
69
|
+
originalSrc: string;
|
|
70
|
+
originalFilename?: string;
|
|
71
|
+
newSrc: string;
|
|
72
|
+
newFilename?: string;
|
|
73
|
+
isOriginalImage?: boolean;
|
|
74
|
+
}>;
|
|
75
|
+
customCode?: {
|
|
76
|
+
id: string;
|
|
77
|
+
js: string;
|
|
78
|
+
css: string;
|
|
79
|
+
pathnames: string[];
|
|
80
|
+
excludePathnames?: string[];
|
|
81
|
+
};
|
|
82
|
+
splitUrlTestLinks?: Record<string, string>;
|
|
83
|
+
content?: Record<string, unknown>;
|
|
84
|
+
checkout?: {
|
|
85
|
+
banner?: {
|
|
86
|
+
title: string;
|
|
87
|
+
status: string;
|
|
88
|
+
spacing: string;
|
|
89
|
+
description: string;
|
|
90
|
+
headingSize: string;
|
|
91
|
+
descriptionSize: string;
|
|
92
|
+
};
|
|
93
|
+
};
|
|
37
94
|
}
|
|
38
95
|
interface Test {
|
|
39
96
|
testId: string;
|
|
@@ -47,21 +104,575 @@ interface Variation {
|
|
|
47
104
|
name: string;
|
|
48
105
|
weight: number;
|
|
49
106
|
isControl?: boolean;
|
|
50
|
-
productId?:
|
|
107
|
+
productId?: string;
|
|
51
108
|
handle?: string;
|
|
52
109
|
price?: string;
|
|
110
|
+
/** Convenience flag: true if this is variation A (index 0) */
|
|
111
|
+
isA?: boolean;
|
|
112
|
+
/** Convenience flag: true if this is variation B (index 1) */
|
|
113
|
+
isB?: boolean;
|
|
114
|
+
/** Convenience flag: true if this is variation C (index 2) */
|
|
115
|
+
isC?: boolean;
|
|
116
|
+
/** Convenience flag: true if this is variation D (index 3) */
|
|
117
|
+
isD?: boolean;
|
|
53
118
|
}
|
|
54
119
|
interface ElevateConfig {
|
|
55
120
|
tests: Test[];
|
|
56
121
|
selectors?: unknown;
|
|
57
122
|
}
|
|
58
123
|
interface ElevateProviderProps {
|
|
124
|
+
/**
|
|
125
|
+
* Shopify store ID (e.g., "mystore.myshopify.com")
|
|
126
|
+
* @required
|
|
127
|
+
*/
|
|
59
128
|
storeId: string;
|
|
129
|
+
/**
|
|
130
|
+
* Cart object from Shopify loader (for Analytics.Provider)
|
|
131
|
+
* @example data.cart from root loader
|
|
132
|
+
*/
|
|
133
|
+
cart?: unknown;
|
|
134
|
+
/**
|
|
135
|
+
* Shop object from Shopify loader (for Analytics.Provider)
|
|
136
|
+
* @example data.shop from root loader
|
|
137
|
+
*/
|
|
138
|
+
shop?: unknown;
|
|
139
|
+
/**
|
|
140
|
+
* Consent object from Shopify loader (for Analytics.Provider)
|
|
141
|
+
* @example data.consent from root loader
|
|
142
|
+
*/
|
|
143
|
+
consent?: unknown;
|
|
144
|
+
/**
|
|
145
|
+
* Enable localized path detection (e.g., /en-us/, /fr-ca/)
|
|
146
|
+
* Only set to true if your homepage uses path-based localization
|
|
147
|
+
* @default false
|
|
148
|
+
*/
|
|
149
|
+
hasLocalizedPaths?: boolean;
|
|
150
|
+
/**
|
|
151
|
+
* Storefront access token for cart attribute updates
|
|
152
|
+
*/
|
|
153
|
+
storefrontAccessToken?: string;
|
|
154
|
+
/**
|
|
155
|
+
* Custom CloudFlare Worker URL (defaults to production endpoint)
|
|
156
|
+
*/
|
|
157
|
+
workerUrl?: string;
|
|
158
|
+
/**
|
|
159
|
+
* Custom CloudFlare Worker URL for orders (defaults to production orders endpoint)
|
|
160
|
+
*/
|
|
161
|
+
ordersWorkerUrl?: string;
|
|
162
|
+
/**
|
|
163
|
+
* Enable flicker prevention - hides content until test assignment is complete
|
|
164
|
+
* Prevents users from seeing content flash/change when variants load
|
|
165
|
+
* @default false
|
|
166
|
+
*/
|
|
167
|
+
preventFlickering?: boolean;
|
|
168
|
+
/**
|
|
169
|
+
* Timeout in milliseconds for flicker prevention failsafe
|
|
170
|
+
* Content will show after this time even if assignment isn't complete
|
|
171
|
+
* @default 3000
|
|
172
|
+
*/
|
|
173
|
+
flickerTimeout?: number;
|
|
60
174
|
children: React.ReactNode;
|
|
61
175
|
}
|
|
62
176
|
interface ElevateContextValue {
|
|
63
177
|
config: ElevateConfig | null;
|
|
178
|
+
/** Store ID for tracking */
|
|
179
|
+
storeId: string;
|
|
180
|
+
/** Storefront access token for cart attribute updates (optional) */
|
|
181
|
+
storefrontAccessToken?: string;
|
|
182
|
+
/** Whether preview mode is active */
|
|
183
|
+
isPreviewMode?: boolean;
|
|
184
|
+
/** Current preview test ID if in preview mode */
|
|
185
|
+
previewTestId?: string | null;
|
|
186
|
+
/** User's detected country code */
|
|
187
|
+
countryCode?: string | null;
|
|
188
|
+
}
|
|
189
|
+
type ExperimentStatus = "draft" | "running" | "paused" | "completed";
|
|
190
|
+
interface ElevateAnalyticsProps {
|
|
191
|
+
/**
|
|
192
|
+
* Shopify store ID (e.g., "mystore.myshopify.com")
|
|
193
|
+
* @required
|
|
194
|
+
*/
|
|
195
|
+
storeId: string;
|
|
196
|
+
/**
|
|
197
|
+
* Enable localized path detection (e.g., /en-us/, /fr-ca/)
|
|
198
|
+
* @default false
|
|
199
|
+
*/
|
|
200
|
+
hasLocalizedPaths?: boolean;
|
|
201
|
+
/**
|
|
202
|
+
* Storefront access token for cart attribute updates
|
|
203
|
+
*/
|
|
204
|
+
storefrontAccessToken?: string;
|
|
205
|
+
/**
|
|
206
|
+
* Custom CloudFlare Worker URL (defaults to production endpoint)
|
|
207
|
+
*/
|
|
208
|
+
workerUrl?: string;
|
|
209
|
+
/**
|
|
210
|
+
* Custom CloudFlare Worker URL for orders (defaults to production orders endpoint)
|
|
211
|
+
*/
|
|
212
|
+
ordersWorkerUrl?: string;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* A/B test assignment included in all events
|
|
216
|
+
*/
|
|
217
|
+
interface TestAssignment {
|
|
218
|
+
test_id: string;
|
|
219
|
+
variant_id: string;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Product info for cart items
|
|
223
|
+
*/
|
|
224
|
+
interface CartItemInput {
|
|
225
|
+
/** Shopify Product ID (numeric, not GID) */
|
|
226
|
+
productId: string;
|
|
227
|
+
/** Shopify Product Variant ID (numeric, not GID) */
|
|
228
|
+
variantId: string;
|
|
229
|
+
/** Product vendor/brand name */
|
|
230
|
+
productVendor?: string;
|
|
231
|
+
/** Item price (single unit) */
|
|
232
|
+
productPrice?: number;
|
|
233
|
+
/** Quantity in cart */
|
|
234
|
+
productQuantity?: number;
|
|
235
|
+
/** Product SKU */
|
|
236
|
+
productSku?: string;
|
|
237
|
+
/** Discount amount on this item */
|
|
238
|
+
totalDiscount?: number;
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Note attribute for checkout
|
|
242
|
+
*/
|
|
243
|
+
interface NoteAttribute {
|
|
244
|
+
key: string;
|
|
245
|
+
value: string;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Base configuration for all tracking events.
|
|
249
|
+
*
|
|
250
|
+
* Note: If you call `initAnalytics()` first (or use ElevateProvider which does this automatically),
|
|
251
|
+
* you don't need to pass storeId to individual tracking calls.
|
|
252
|
+
*/
|
|
253
|
+
interface BaseTrackingConfig {
|
|
254
|
+
/**
|
|
255
|
+
* Shopify store ID (e.g., "mystore.myshopify.com")
|
|
256
|
+
* Optional if initAnalytics() was called or ElevateProvider is used.
|
|
257
|
+
*/
|
|
258
|
+
storeId?: string;
|
|
259
|
+
/**
|
|
260
|
+
* Enable localized path detection (e.g., /en-us/, /fr-ca/)
|
|
261
|
+
* @default false
|
|
262
|
+
*/
|
|
263
|
+
hasLocalizedPaths?: boolean;
|
|
264
|
+
/**
|
|
265
|
+
* Cart/shop currency code (e.g., "USD", "EUR")
|
|
266
|
+
* If not provided, will try to detect from Shopify or omit.
|
|
267
|
+
*/
|
|
268
|
+
currency?: string;
|
|
269
|
+
/**
|
|
270
|
+
* Custom CloudFlare Worker URL (optional)
|
|
271
|
+
*/
|
|
272
|
+
workerUrl?: string;
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Parameters for tracking a page view
|
|
276
|
+
* @example After initAnalytics() or inside ElevateProvider (recommended)
|
|
277
|
+
* ```ts
|
|
278
|
+
* await trackPageView(); // No params needed!
|
|
279
|
+
* await trackPageView({ currency: "USD" }); // Optional currency
|
|
280
|
+
* ```
|
|
281
|
+
* @example Standalone (without init)
|
|
282
|
+
* ```ts
|
|
283
|
+
* await trackPageView({ storeId: "mystore.myshopify.com" });
|
|
284
|
+
* ```
|
|
285
|
+
*/
|
|
286
|
+
interface TrackPageViewParams extends BaseTrackingConfig {
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Parameters for tracking a product view
|
|
290
|
+
* @example After initAnalytics() or inside ElevateProvider (recommended)
|
|
291
|
+
* ```ts
|
|
292
|
+
* await trackProductView({
|
|
293
|
+
* productId: "123456789",
|
|
294
|
+
* productPrice: 99.99,
|
|
295
|
+
* });
|
|
296
|
+
* ```
|
|
297
|
+
* @example With all optional fields
|
|
298
|
+
* ```ts
|
|
299
|
+
* await trackProductView({
|
|
300
|
+
* productId: "123456789",
|
|
301
|
+
* productVendor: "Nike",
|
|
302
|
+
* productPrice: 99.99,
|
|
303
|
+
* productSku: "NIKE-001",
|
|
304
|
+
* currency: "USD",
|
|
305
|
+
* });
|
|
306
|
+
* ```
|
|
307
|
+
*/
|
|
308
|
+
interface TrackProductViewParams extends BaseTrackingConfig {
|
|
309
|
+
/**
|
|
310
|
+
* Shopify Product ID (numeric string, not GID)
|
|
311
|
+
* @required
|
|
312
|
+
*/
|
|
313
|
+
productId: string;
|
|
314
|
+
/** Product vendor/brand name */
|
|
315
|
+
productVendor?: string;
|
|
316
|
+
/** Product price */
|
|
317
|
+
productPrice?: number;
|
|
318
|
+
/** Product SKU */
|
|
319
|
+
productSku?: string;
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Parameters for tracking add to cart
|
|
323
|
+
* @example After initAnalytics() or inside ElevateProvider (recommended)
|
|
324
|
+
* ```ts
|
|
325
|
+
* await trackAddToCart({
|
|
326
|
+
* productId: "123456789",
|
|
327
|
+
* variantId: "987654321",
|
|
328
|
+
* productPrice: 99.99,
|
|
329
|
+
* productQuantity: 1,
|
|
330
|
+
* });
|
|
331
|
+
* ```
|
|
332
|
+
* @example With cart ID for automatic attribute updates
|
|
333
|
+
* ```ts
|
|
334
|
+
* await trackAddToCart({
|
|
335
|
+
* productId: "123456789",
|
|
336
|
+
* variantId: "987654321",
|
|
337
|
+
* productPrice: 99.99,
|
|
338
|
+
* productQuantity: 1,
|
|
339
|
+
* cartId: "gid://shopify/Cart/abc123",
|
|
340
|
+
* });
|
|
341
|
+
* ```
|
|
342
|
+
*/
|
|
343
|
+
interface TrackAddToCartParams extends BaseTrackingConfig {
|
|
344
|
+
/**
|
|
345
|
+
* Shopify Product ID (numeric string, not GID)
|
|
346
|
+
* @required
|
|
347
|
+
*/
|
|
348
|
+
productId: string;
|
|
349
|
+
/**
|
|
350
|
+
* Shopify Product Variant ID (numeric string, not GID)
|
|
351
|
+
* @required
|
|
352
|
+
*/
|
|
353
|
+
variantId: string;
|
|
354
|
+
/** Product vendor/brand name */
|
|
355
|
+
productVendor?: string;
|
|
356
|
+
/** Product price (single unit) */
|
|
357
|
+
productPrice?: number;
|
|
358
|
+
/** Quantity being added */
|
|
359
|
+
productQuantity?: number;
|
|
360
|
+
/** Product SKU */
|
|
361
|
+
productSku?: string;
|
|
362
|
+
/**
|
|
363
|
+
* Cart ID (GID or token) - if provided, cart attributes will be updated automatically
|
|
364
|
+
* @example "gid://shopify/Cart/abc123" or "abc123"
|
|
365
|
+
*/
|
|
366
|
+
cartId?: string;
|
|
367
|
+
/**
|
|
368
|
+
* Storefront Access Token - REQUIRED if cartId is provided
|
|
369
|
+
* ✅ Safe to use client-side - this is a public token
|
|
370
|
+
*/
|
|
371
|
+
storefrontAccessToken?: string;
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Parameters for tracking remove from cart
|
|
375
|
+
* @example
|
|
376
|
+
* ```ts
|
|
377
|
+
* await trackRemoveFromCart({
|
|
378
|
+
* productId: "123456789",
|
|
379
|
+
* variantId: "987654321",
|
|
380
|
+
* productQuantity: 1,
|
|
381
|
+
* });
|
|
382
|
+
* ```
|
|
383
|
+
*/
|
|
384
|
+
interface TrackRemoveFromCartParams extends BaseTrackingConfig {
|
|
385
|
+
/**
|
|
386
|
+
* Shopify Product ID (numeric string, not GID)
|
|
387
|
+
* @required
|
|
388
|
+
*/
|
|
389
|
+
productId: string;
|
|
390
|
+
/**
|
|
391
|
+
* Shopify Product Variant ID (numeric string, not GID)
|
|
392
|
+
* @required
|
|
393
|
+
*/
|
|
394
|
+
variantId: string;
|
|
395
|
+
/** Product vendor/brand name */
|
|
396
|
+
productVendor?: string;
|
|
397
|
+
/** Product price (single unit) */
|
|
398
|
+
productPrice?: number;
|
|
399
|
+
/** Quantity being removed */
|
|
400
|
+
productQuantity?: number;
|
|
401
|
+
/** Product SKU */
|
|
402
|
+
productSku?: string;
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Parameters for tracking cart view
|
|
406
|
+
* @example
|
|
407
|
+
* ```ts
|
|
408
|
+
* await trackCartView({
|
|
409
|
+
* cartTotalPrice: 199.98,
|
|
410
|
+
* cartTotalQuantity: 2,
|
|
411
|
+
* cartItems: [{ productId: "123", variantId: "456", productPrice: 99.99 }],
|
|
412
|
+
* });
|
|
413
|
+
* ```
|
|
414
|
+
*/
|
|
415
|
+
interface TrackCartViewParams extends BaseTrackingConfig {
|
|
416
|
+
/** Total cart price */
|
|
417
|
+
cartTotalPrice?: number;
|
|
418
|
+
/** Total items in cart */
|
|
419
|
+
cartTotalQuantity?: number;
|
|
420
|
+
/** Cart line items */
|
|
421
|
+
cartItems?: CartItemInput[];
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* Parameters for tracking search submission
|
|
425
|
+
* @example
|
|
426
|
+
* ```ts
|
|
427
|
+
* await trackSearchSubmitted({ searchQuery: "running shoes" });
|
|
428
|
+
* ```
|
|
429
|
+
*/
|
|
430
|
+
interface TrackSearchSubmittedParams extends BaseTrackingConfig {
|
|
431
|
+
/**
|
|
432
|
+
* Search query string
|
|
433
|
+
* @required
|
|
434
|
+
*/
|
|
435
|
+
searchQuery: string;
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* Parameters for tracking checkout started
|
|
439
|
+
* @example
|
|
440
|
+
* ```ts
|
|
441
|
+
* await trackCheckoutStarted({
|
|
442
|
+
* cartTotalPrice: 109.98,
|
|
443
|
+
* cartItems: [...],
|
|
444
|
+
* });
|
|
445
|
+
* ```
|
|
446
|
+
*/
|
|
447
|
+
interface TrackCheckoutStartedParams extends BaseTrackingConfig {
|
|
448
|
+
/** Total checkout price (including shipping, tax) */
|
|
449
|
+
cartTotalPrice?: number;
|
|
450
|
+
/** Subtotal (before shipping, tax) */
|
|
451
|
+
cartSubtotalPrice?: number;
|
|
452
|
+
/** Shipping cost */
|
|
453
|
+
cartShippingPrice?: number;
|
|
454
|
+
/** Tax amount */
|
|
455
|
+
cartTaxAmount?: number;
|
|
456
|
+
/** Total discount applied */
|
|
457
|
+
cartDiscountAmount?: number;
|
|
458
|
+
/** Shopify Customer ID */
|
|
459
|
+
customerId?: string;
|
|
460
|
+
/** Checkout line items */
|
|
461
|
+
cartItems?: CartItemInput[];
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* Parameters for tracking checkout completed (order placed)
|
|
465
|
+
* NOTE: This sends to the orders worker endpoint
|
|
466
|
+
* @example
|
|
467
|
+
* ```ts
|
|
468
|
+
* await trackCheckoutCompleted({
|
|
469
|
+
* orderId: "order_123456",
|
|
470
|
+
* cartTotalPrice: 109.98,
|
|
471
|
+
* cartItems: [...],
|
|
472
|
+
* });
|
|
473
|
+
* ```
|
|
474
|
+
*/
|
|
475
|
+
interface TrackCheckoutCompletedParams extends Omit<BaseTrackingConfig, "workerUrl"> {
|
|
476
|
+
/**
|
|
477
|
+
* Shopify Order ID
|
|
478
|
+
* @required
|
|
479
|
+
*/
|
|
480
|
+
orderId: string;
|
|
481
|
+
/** Total checkout price (including shipping, tax) */
|
|
482
|
+
cartTotalPrice?: number;
|
|
483
|
+
/** Subtotal (before shipping, tax) */
|
|
484
|
+
cartSubtotalPrice?: number;
|
|
485
|
+
/** Shipping cost */
|
|
486
|
+
cartShippingPrice?: number;
|
|
487
|
+
/** Tax amount */
|
|
488
|
+
cartTaxAmount?: number;
|
|
489
|
+
/** Total discount applied */
|
|
490
|
+
cartDiscountAmount?: number;
|
|
491
|
+
/** Shopify Customer ID */
|
|
492
|
+
customerId?: string;
|
|
493
|
+
/** Whether this is customer's first order */
|
|
494
|
+
isFirstOrder?: boolean;
|
|
495
|
+
/** Order note attributes (for A/B test attribution) */
|
|
496
|
+
noteAttributes?: NoteAttribute[];
|
|
497
|
+
/** Checkout line items */
|
|
498
|
+
cartItems?: CartItemInput[];
|
|
499
|
+
/**
|
|
500
|
+
* Custom orders worker URL (optional)
|
|
501
|
+
* Note: Uses different endpoint than other events
|
|
502
|
+
*/
|
|
503
|
+
ordersWorkerUrl?: string;
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
506
|
+
* Parameters for auto page view tracking hook
|
|
507
|
+
* @example After initAnalytics() or inside ElevateProvider
|
|
508
|
+
* ```ts
|
|
509
|
+
* // In your layout component
|
|
510
|
+
* usePageViewTracking({ enabled: true });
|
|
511
|
+
* ```
|
|
512
|
+
* @example With Next.js usePathname (recommended)
|
|
513
|
+
* ```ts
|
|
514
|
+
* const pathname = usePathname();
|
|
515
|
+
* usePageViewTracking({ pathname, enabled: true });
|
|
516
|
+
* ```
|
|
517
|
+
*/
|
|
518
|
+
interface UsePageViewTrackingParams extends BaseTrackingConfig {
|
|
519
|
+
/**
|
|
520
|
+
* Enable/disable tracking
|
|
521
|
+
* @default true
|
|
522
|
+
*/
|
|
523
|
+
enabled?: boolean;
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* Cart item as sent to the worker
|
|
527
|
+
* @internal
|
|
528
|
+
*/
|
|
529
|
+
interface CartItemPayload {
|
|
530
|
+
product_id: string;
|
|
531
|
+
variant_id: string;
|
|
532
|
+
product_vendor?: string;
|
|
533
|
+
product_price: number | null;
|
|
534
|
+
product_quantity: number | null;
|
|
535
|
+
product_sku?: string;
|
|
536
|
+
total_discount?: number | null;
|
|
537
|
+
vendor?: string;
|
|
538
|
+
total_price?: number | null;
|
|
539
|
+
quantity?: number | null;
|
|
540
|
+
sku?: string;
|
|
64
541
|
}
|
|
542
|
+
/**
|
|
543
|
+
* Full event payload sent to CloudFlare Worker
|
|
544
|
+
* @internal - Users don't need to construct this directly
|
|
545
|
+
*/
|
|
546
|
+
interface EventPayload {
|
|
547
|
+
pixel_event_id: string;
|
|
548
|
+
shop_name: string;
|
|
549
|
+
timestamp: string;
|
|
550
|
+
event_type: string;
|
|
551
|
+
client_id?: string;
|
|
552
|
+
visitor_id: string;
|
|
553
|
+
session_id: string;
|
|
554
|
+
cart_token: string | null;
|
|
555
|
+
page_url: string;
|
|
556
|
+
page_pathname: string;
|
|
557
|
+
page_search: string;
|
|
558
|
+
referrer_url: string;
|
|
559
|
+
referrer_source: string;
|
|
560
|
+
previous_page: string;
|
|
561
|
+
page_entry: string;
|
|
562
|
+
page_entry_path: string;
|
|
563
|
+
page_type: string;
|
|
564
|
+
utm_medium: string;
|
|
565
|
+
utm_source: string;
|
|
566
|
+
utm_campaign: string;
|
|
567
|
+
utm_content: string;
|
|
568
|
+
utm_term: string;
|
|
569
|
+
gclid: string;
|
|
570
|
+
fbclid: string;
|
|
571
|
+
pins_campaign_id?: string;
|
|
572
|
+
epik?: string;
|
|
573
|
+
browser_info: string;
|
|
574
|
+
os_info: string;
|
|
575
|
+
device_type: string;
|
|
576
|
+
language: string;
|
|
577
|
+
root_route: string;
|
|
578
|
+
user_agent: string;
|
|
579
|
+
user_agent_no_browser?: string;
|
|
580
|
+
is_first_visit?: boolean;
|
|
581
|
+
shopify_country?: string;
|
|
582
|
+
cart_currency?: string;
|
|
583
|
+
ab_test_assignments: TestAssignment[];
|
|
584
|
+
ab_test_views: TestAssignment[];
|
|
585
|
+
is_first_order?: boolean | null;
|
|
586
|
+
product_id?: string;
|
|
587
|
+
product_vendor?: string;
|
|
588
|
+
product_price?: number | null;
|
|
589
|
+
product_sku?: string;
|
|
590
|
+
variant_id?: string;
|
|
591
|
+
product_quantity?: number | null;
|
|
592
|
+
cart_total_price?: number | null;
|
|
593
|
+
cart_subtotal_price?: number | null;
|
|
594
|
+
cart_total_quantity?: number | null;
|
|
595
|
+
cart_shipping_price?: number | null;
|
|
596
|
+
cart_tax_amount?: number | null;
|
|
597
|
+
cart_discount_amount?: number | null;
|
|
598
|
+
cart_items?: CartItemPayload[];
|
|
599
|
+
search_query?: string;
|
|
600
|
+
order_id?: string;
|
|
601
|
+
customer_id?: string;
|
|
602
|
+
note_attributes?: NoteAttribute[];
|
|
603
|
+
token?: string;
|
|
604
|
+
exclude?: boolean;
|
|
605
|
+
}
|
|
606
|
+
/**
|
|
607
|
+
* Options for updating cart attributes
|
|
608
|
+
*
|
|
609
|
+
* ## For Hydrogen Stores
|
|
610
|
+
* Use your built-in storefront client with `getCartAttributesPayload()` instead.
|
|
611
|
+
*
|
|
612
|
+
* ## For Next.js / Other Stores
|
|
613
|
+
* You MUST provide `storefrontAccessToken`.
|
|
614
|
+
*
|
|
615
|
+
* ✅ **The Storefront Access Token is SAFE to use client-side!**
|
|
616
|
+
*
|
|
617
|
+
* It's a PUBLIC token that Shopify specifically designed for browser use.
|
|
618
|
+
* It can only:
|
|
619
|
+
* - Read products, collections, pages
|
|
620
|
+
* - Create and update carts
|
|
621
|
+
* - Create checkouts
|
|
622
|
+
*
|
|
623
|
+
* It CANNOT:
|
|
624
|
+
* - Delete products
|
|
625
|
+
* - Access admin functions
|
|
626
|
+
* - Read orders or customer PII
|
|
627
|
+
* - Do anything destructive
|
|
628
|
+
*
|
|
629
|
+
* Get your token from: Shopify Admin → Settings → Apps → Develop apps
|
|
630
|
+
*
|
|
631
|
+
* @example
|
|
632
|
+
* ```ts
|
|
633
|
+
* // Next.js - safe to use client-side!
|
|
634
|
+
* await updateCartAttributes(cartId, {
|
|
635
|
+
* storefrontAccessToken: process.env.NEXT_PUBLIC_STOREFRONT_TOKEN
|
|
636
|
+
* });
|
|
637
|
+
* ```
|
|
638
|
+
*/
|
|
639
|
+
interface CartAttributesOptions {
|
|
640
|
+
/**
|
|
641
|
+
* Custom Storefront API URL
|
|
642
|
+
*
|
|
643
|
+
* Only needed if you have a custom proxy or different API endpoint.
|
|
644
|
+
* If provided, storefrontAccessToken may not be required (if your proxy handles auth).
|
|
645
|
+
*
|
|
646
|
+
* @default "https://{storeDomain}/api/2025-01/graphql.json"
|
|
647
|
+
*/
|
|
648
|
+
storefrontApiUrl?: string;
|
|
649
|
+
/**
|
|
650
|
+
* Shopify Storefront Access Token
|
|
651
|
+
*
|
|
652
|
+
* ⚠️ **Required for Next.js and non-Hydrogen stores**
|
|
653
|
+
*
|
|
654
|
+
* ✅ Safe to expose client-side - this is a PUBLIC token with limited permissions.
|
|
655
|
+
*
|
|
656
|
+
* Get it from: Shopify Admin → Settings → Apps → Develop apps → API credentials
|
|
657
|
+
*
|
|
658
|
+
* @example "shpat_xxxxxxxxxxxxxxxxxxxxx"
|
|
659
|
+
*/
|
|
660
|
+
storefrontAccessToken?: string;
|
|
661
|
+
}
|
|
662
|
+
/**
|
|
663
|
+
* Cart attribute input for GraphQL mutation
|
|
664
|
+
*
|
|
665
|
+
* These key-value pairs are attached to the Shopify cart for order attribution.
|
|
666
|
+
*/
|
|
667
|
+
interface CartAttributeInput {
|
|
668
|
+
/** Attribute key (e.g., "_eabTestsList") */
|
|
669
|
+
key: string;
|
|
670
|
+
/** Attribute value (JSON string for complex data) */
|
|
671
|
+
value: string;
|
|
672
|
+
}
|
|
673
|
+
/**
|
|
674
|
+
* @deprecated Use TrackPageViewParams instead
|
|
675
|
+
*/
|
|
65
676
|
interface TrackingEvent {
|
|
66
677
|
experimentId: string;
|
|
67
678
|
variantId: string;
|
|
@@ -69,7 +680,6 @@ interface TrackingEvent {
|
|
|
69
680
|
timestamp: number;
|
|
70
681
|
metadata?: Record<string, unknown>;
|
|
71
682
|
}
|
|
72
|
-
type ExperimentStatus = "draft" | "running" | "paused" | "completed";
|
|
73
683
|
|
|
74
684
|
/**
|
|
75
685
|
* Assigns a variant based on weighted distribution
|
|
@@ -83,39 +693,829 @@ declare function calculateRevenueLift(controlRevenue: number, variantRevenue: nu
|
|
|
83
693
|
confidence: number;
|
|
84
694
|
};
|
|
85
695
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
696
|
+
/**
|
|
697
|
+
* Cookie and Session Storage utilities
|
|
698
|
+
*/
|
|
699
|
+
/**
|
|
700
|
+
* Generate a UUID v4
|
|
701
|
+
*/
|
|
702
|
+
declare function uuidv4(): string;
|
|
703
|
+
/**
|
|
704
|
+
* Set a cookie with 1 year expiration
|
|
705
|
+
*/
|
|
706
|
+
declare function setCookie(name: string, value: string): void;
|
|
707
|
+
/**
|
|
708
|
+
* Get a cookie value by name
|
|
709
|
+
*/
|
|
710
|
+
declare function getCookie(name: string): string | null;
|
|
711
|
+
/**
|
|
712
|
+
* Get a JSON-parsed cookie value
|
|
713
|
+
*/
|
|
714
|
+
declare function getJsonCookie<T = Record<string, unknown>>(name: string): T | null;
|
|
715
|
+
/**
|
|
716
|
+
* Delete a cookie
|
|
717
|
+
*/
|
|
718
|
+
declare function deleteCookie(cookieName: string): void;
|
|
719
|
+
/**
|
|
720
|
+
* Set a session storage item
|
|
721
|
+
*/
|
|
722
|
+
declare function setSessionItem(name: string, value: unknown): void;
|
|
723
|
+
/**
|
|
724
|
+
* Get a session storage item
|
|
725
|
+
*/
|
|
726
|
+
declare function getSessionItem(name: string): string | null;
|
|
727
|
+
/**
|
|
728
|
+
* Get a JSON-parsed session storage item
|
|
729
|
+
*/
|
|
730
|
+
declare function getJsonSessionItem<T = unknown>(name: string): T | null;
|
|
731
|
+
/**
|
|
732
|
+
* Initialize visitor ID - creates eabUserId cookie if it doesn't exist
|
|
733
|
+
*/
|
|
734
|
+
declare function initializeVisitorId(): string;
|
|
735
|
+
/**
|
|
736
|
+
* Get or create visitor ID
|
|
737
|
+
*/
|
|
738
|
+
declare function getVisitorId(): string;
|
|
739
|
+
/**
|
|
740
|
+
* Initialize session ID - creates eabSessionId in sessionStorage if it doesn't exist
|
|
741
|
+
*/
|
|
742
|
+
declare function initializeSessionId(): string;
|
|
743
|
+
/**
|
|
744
|
+
* Get or create session ID
|
|
745
|
+
*/
|
|
746
|
+
declare function getSessionId(): string;
|
|
747
|
+
/**
|
|
748
|
+
* Store referrer and entry page data in sessionStorage
|
|
749
|
+
*/
|
|
750
|
+
declare function setReferrerData(referrer: string, entryPage: string): void;
|
|
751
|
+
/**
|
|
752
|
+
* Get referrer data from sessionStorage
|
|
753
|
+
*/
|
|
754
|
+
declare function getReferrerData(): {
|
|
755
|
+
referrer: string;
|
|
756
|
+
entryPage: string;
|
|
757
|
+
};
|
|
758
|
+
|
|
759
|
+
/**
|
|
760
|
+
* Variant assignment logic
|
|
761
|
+
*/
|
|
762
|
+
|
|
763
|
+
interface TestList {
|
|
764
|
+
[testId: string]: string;
|
|
91
765
|
}
|
|
92
766
|
/**
|
|
93
|
-
*
|
|
94
|
-
* Fetches config from ElevateProvider context based on testId
|
|
767
|
+
* Get the test list from ABTL cookie
|
|
95
768
|
*/
|
|
96
|
-
declare function
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
769
|
+
declare function getTestList(): TestList;
|
|
770
|
+
/**
|
|
771
|
+
* Save test list to ABTL cookie
|
|
772
|
+
*/
|
|
773
|
+
declare function saveTestList(testList: TestList): void;
|
|
774
|
+
/**
|
|
775
|
+
* Get assigned variant for a test from ABTL cookie
|
|
776
|
+
*/
|
|
777
|
+
declare function getAssignedVariant(testId: string): string | null;
|
|
778
|
+
/**
|
|
779
|
+
* Assign and persist variant for a test
|
|
780
|
+
*/
|
|
781
|
+
declare function assignAndPersistVariant(testId: string, test: Test, userId: string): Variation | null;
|
|
782
|
+
/**
|
|
783
|
+
* Check if test should be shown based on traffic percentage
|
|
784
|
+
*/
|
|
785
|
+
declare function shouldShowTest(test: Test): boolean;
|
|
786
|
+
|
|
787
|
+
/**
|
|
788
|
+
* Tracking utilities for views and participation
|
|
789
|
+
*/
|
|
790
|
+
/**
|
|
791
|
+
* Track unique view for a test (ABAU cookie)
|
|
792
|
+
*/
|
|
793
|
+
declare function trackUniqueView(testId: string): void;
|
|
794
|
+
/**
|
|
795
|
+
* Track session view for a test (ABAV session storage)
|
|
796
|
+
*/
|
|
797
|
+
declare function trackSessionView(testId: string): void;
|
|
798
|
+
/**
|
|
799
|
+
* Track both unique and session views
|
|
800
|
+
*/
|
|
801
|
+
declare function trackViews(testId: string): void;
|
|
802
|
+
/**
|
|
803
|
+
* Check if test has been viewed in this session
|
|
804
|
+
*/
|
|
805
|
+
declare function hasSessionView(testId: string): boolean;
|
|
806
|
+
/**
|
|
807
|
+
* Check if test has a unique view
|
|
808
|
+
*/
|
|
809
|
+
declare function hasUniqueView(testId: string): boolean;
|
|
810
|
+
|
|
811
|
+
/**
|
|
812
|
+
* Condition checking utilities for targeting and filtering
|
|
813
|
+
*/
|
|
814
|
+
/**
|
|
815
|
+
* Detect device type
|
|
816
|
+
*/
|
|
817
|
+
declare function getDeviceType(): "desktop" | "tablet" | "mobile";
|
|
818
|
+
/**
|
|
819
|
+
* Check if Facebook in-app browser
|
|
820
|
+
*/
|
|
821
|
+
declare function checkFacebookBrowser(): boolean;
|
|
822
|
+
/**
|
|
823
|
+
* Check if Instagram in-app browser
|
|
824
|
+
*/
|
|
825
|
+
declare function checkInstagramBrowser(): boolean;
|
|
826
|
+
/**
|
|
827
|
+
* Check if TikTok in-app browser
|
|
828
|
+
*/
|
|
829
|
+
declare function checkTikTokBrowser(): boolean;
|
|
830
|
+
/**
|
|
831
|
+
* Check if Pinterest in-app browser
|
|
832
|
+
*/
|
|
833
|
+
declare function checkPinterestBrowser(): boolean;
|
|
834
|
+
/**
|
|
835
|
+
* Get traffic source
|
|
836
|
+
*/
|
|
837
|
+
declare function getTrafficSource(): string;
|
|
838
|
+
|
|
839
|
+
/**
|
|
840
|
+
* Preview Mode Utilities
|
|
841
|
+
*
|
|
842
|
+
* Enables QA/preview functionality for A/B tests via URL parameters.
|
|
843
|
+
*
|
|
844
|
+
* URL Format:
|
|
845
|
+
* ?eabUserPreview=true&abtid=<test_id>&eab_tests=<shortid>_<variation>_<seen>
|
|
846
|
+
*
|
|
847
|
+
* Example:
|
|
848
|
+
* https://store.com/?eabUserPreview=true&abtid=b6e2ecb8-e35a-450e-ae49-bdc560cf0fd7&eab_tests=f0fd7_29913_1
|
|
849
|
+
*/
|
|
850
|
+
/**
|
|
851
|
+
* Preview mode state
|
|
852
|
+
*/
|
|
853
|
+
interface PreviewState {
|
|
854
|
+
/** Whether preview mode is active */
|
|
855
|
+
isPreview: boolean;
|
|
856
|
+
/** The test ID being previewed (full UUID or short ID) */
|
|
857
|
+
previewTestId: string | null;
|
|
858
|
+
/** Forced test assignments from URL params */
|
|
859
|
+
forcedAssignments: Record<string, string>;
|
|
860
|
+
/** Tests that have been marked as "seen" in preview */
|
|
861
|
+
previewedViews: Record<string, boolean>;
|
|
862
|
+
}
|
|
863
|
+
/**
|
|
864
|
+
* Get preview state from URL parameters and cookies
|
|
865
|
+
*/
|
|
866
|
+
declare function getPreviewState(): PreviewState;
|
|
867
|
+
/**
|
|
868
|
+
* Check if a test matches the preview test ID
|
|
869
|
+
* Supports both full UUID and short ID (last 5 chars) matching
|
|
870
|
+
*/
|
|
871
|
+
declare function isPreviewTest(testId: string, previewTestId: string | null): boolean;
|
|
872
|
+
/**
|
|
873
|
+
* Get forced variation for a test in preview mode
|
|
874
|
+
* Returns null if no forced assignment exists
|
|
875
|
+
*/
|
|
876
|
+
declare function getPreviewVariation(testId: string, previewState: PreviewState): string | null;
|
|
877
|
+
/**
|
|
878
|
+
* Build eab_tests URL parameter string from test assignments
|
|
879
|
+
* Used for sharing preview URLs with Facebook/Instagram traffic
|
|
880
|
+
*/
|
|
881
|
+
declare function buildEabTestsParam(testAssignments: Record<string, string>, viewedTests: Record<string, boolean>): string;
|
|
882
|
+
/**
|
|
883
|
+
* Update URL with test parameters for social media browsers (FB/IG/TikTok)
|
|
884
|
+
* These browsers often lose cookies, so we persist test assignments in URL
|
|
885
|
+
*/
|
|
886
|
+
declare function updateUrlWithTestParams(testAssignments: Record<string, string>, viewedTests: Record<string, boolean>, visitorId?: string): void;
|
|
887
|
+
/**
|
|
888
|
+
* Clear preview mode
|
|
889
|
+
*/
|
|
890
|
+
declare function clearPreviewMode(): void;
|
|
891
|
+
/**
|
|
892
|
+
* Check if current session is in preview mode
|
|
893
|
+
*/
|
|
894
|
+
declare function isInPreviewMode(): boolean;
|
|
895
|
+
|
|
896
|
+
/**
|
|
897
|
+
* Geo-targeting Utilities
|
|
898
|
+
*
|
|
899
|
+
* Provides country detection and geo-based targeting for A/B tests.
|
|
900
|
+
*/
|
|
901
|
+
/**
|
|
902
|
+
* Geo-location data
|
|
903
|
+
*/
|
|
904
|
+
interface GeoLocation {
|
|
905
|
+
/** ISO 3166-1 alpha-2 country code (e.g., "US", "GB", "CA") */
|
|
906
|
+
country: string | null;
|
|
907
|
+
/** Region/state code (if available) */
|
|
908
|
+
region?: string | null;
|
|
909
|
+
/** City name (if available) */
|
|
910
|
+
city?: string | null;
|
|
911
|
+
}
|
|
912
|
+
/**
|
|
913
|
+
* Get the user's country code from various sources
|
|
914
|
+
* Priority: URL param > Shopify localization > our cookie > localStorage
|
|
915
|
+
*/
|
|
916
|
+
declare function getCountryCode(): string | null;
|
|
917
|
+
/**
|
|
918
|
+
* Get full geo-location data
|
|
919
|
+
*/
|
|
920
|
+
declare function getGeoLocation(): GeoLocation;
|
|
921
|
+
/**
|
|
922
|
+
* Set the user's country code (for manual override or after geo detection)
|
|
923
|
+
*/
|
|
924
|
+
declare function setCountryCode(countryCode: string): void;
|
|
925
|
+
/**
|
|
926
|
+
* Set full geo-location data
|
|
927
|
+
*/
|
|
928
|
+
declare function setGeoLocation(geo: GeoLocation): void;
|
|
929
|
+
/**
|
|
930
|
+
* Check if user's country matches a list of allowed countries
|
|
931
|
+
*/
|
|
932
|
+
declare function isCountryIncluded(allowedCountries: string[], userCountry?: string | null): boolean;
|
|
933
|
+
/**
|
|
934
|
+
* Check if user's country is in an excluded list
|
|
935
|
+
*/
|
|
936
|
+
declare function isCountryExcluded(excludedCountries: string[], userCountry?: string | null): boolean;
|
|
937
|
+
/**
|
|
938
|
+
* Check if user matches geo-targeting rules
|
|
939
|
+
* Returns true if user should be included in the test
|
|
940
|
+
*/
|
|
941
|
+
declare function matchesGeoTargeting(rules: {
|
|
942
|
+
includeCountries?: string[];
|
|
943
|
+
excludeCountries?: string[];
|
|
944
|
+
}): boolean;
|
|
945
|
+
/**
|
|
946
|
+
* Common country code constants for convenience
|
|
947
|
+
*/
|
|
948
|
+
declare const COUNTRIES: {
|
|
949
|
+
readonly US: "US";
|
|
950
|
+
readonly CA: "CA";
|
|
951
|
+
readonly GB: "GB";
|
|
952
|
+
readonly AU: "AU";
|
|
953
|
+
readonly DE: "DE";
|
|
954
|
+
readonly FR: "FR";
|
|
955
|
+
readonly JP: "JP";
|
|
956
|
+
readonly MX: "MX";
|
|
957
|
+
readonly BR: "BR";
|
|
958
|
+
readonly IN: "IN";
|
|
959
|
+
};
|
|
960
|
+
/**
|
|
961
|
+
* Region groupings for common use cases
|
|
962
|
+
*/
|
|
963
|
+
declare const REGIONS: {
|
|
964
|
+
readonly NORTH_AMERICA: readonly ["US", "CA", "MX"];
|
|
965
|
+
readonly EUROPE: readonly ["GB", "DE", "FR", "IT", "ES", "NL", "BE", "AT", "CH", "PL", "SE", "NO", "DK", "FI", "IE", "PT"];
|
|
966
|
+
readonly APAC: readonly ["AU", "NZ", "JP", "KR", "SG", "HK", "TW", "TH", "MY", "PH", "ID", "VN", "IN"];
|
|
967
|
+
readonly LATAM: readonly ["MX", "BR", "AR", "CL", "CO", "PE"];
|
|
968
|
+
};
|
|
969
|
+
|
|
970
|
+
/**
|
|
971
|
+
* Anti-Flicker Utilities
|
|
972
|
+
*
|
|
973
|
+
* Prevents visual flickering during A/B test assignment by hiding content
|
|
974
|
+
* until the variant is determined. Uses a CSS-based approach for performance.
|
|
975
|
+
*
|
|
976
|
+
* Note: Called "preventFlickering" in our API to differentiate from competitors.
|
|
977
|
+
*/
|
|
978
|
+
/**
|
|
979
|
+
* Inject the flicker prevention CSS styles
|
|
980
|
+
* This should be called as early as possible (ideally in <head>)
|
|
981
|
+
*/
|
|
982
|
+
declare function injectFlickerStyles(timeout?: number): void;
|
|
983
|
+
/**
|
|
984
|
+
* Hide the page/element to prevent flicker
|
|
985
|
+
* Call this before test assignment begins
|
|
986
|
+
*/
|
|
987
|
+
declare function hideForFlicker(selector?: string): void;
|
|
988
|
+
/**
|
|
989
|
+
* Show the page/element after test assignment is complete
|
|
990
|
+
* Call this after variant is determined
|
|
991
|
+
*/
|
|
992
|
+
declare function revealAfterFlicker(selector?: string): void;
|
|
993
|
+
/**
|
|
994
|
+
* Setup flicker prevention with automatic reveal
|
|
995
|
+
* Returns a function to call when assignment is complete
|
|
996
|
+
*
|
|
997
|
+
* @param selector - CSS selector for element to hide (default: "body")
|
|
998
|
+
* @param timeout - Maximum time to wait before revealing (default: 3000ms)
|
|
999
|
+
* @returns Function to call when test assignment is complete
|
|
1000
|
+
*
|
|
1001
|
+
* @example
|
|
1002
|
+
* ```tsx
|
|
1003
|
+
* // In your app initialization
|
|
1004
|
+
* const reveal = setupFlickerPrevention();
|
|
1005
|
+
*
|
|
1006
|
+
* // After test assignment
|
|
1007
|
+
* reveal();
|
|
1008
|
+
* ```
|
|
1009
|
+
*/
|
|
1010
|
+
declare function setupFlickerPrevention(selector?: string, timeout?: number): () => void;
|
|
1011
|
+
/**
|
|
1012
|
+
* Remove all flicker prevention styles and classes
|
|
1013
|
+
* Useful for cleanup or when disabling the feature
|
|
1014
|
+
*/
|
|
1015
|
+
declare function cleanupFlickerPrevention(): void;
|
|
1016
|
+
/**
|
|
1017
|
+
* Check if flicker prevention is currently active
|
|
1018
|
+
*/
|
|
1019
|
+
declare function isFlickerPreventionActive(): boolean;
|
|
1020
|
+
/**
|
|
1021
|
+
* Script snippet for inline injection in <head>
|
|
1022
|
+
* Use this when you need synchronous flicker prevention before React hydrates
|
|
1023
|
+
*
|
|
1024
|
+
* @example
|
|
1025
|
+
* ```tsx
|
|
1026
|
+
* // In your _document.tsx or layout.tsx
|
|
1027
|
+
* <script dangerouslySetInnerHTML={{ __html: getFlickerPreventionScript() }} />
|
|
1028
|
+
* ```
|
|
1029
|
+
*/
|
|
1030
|
+
declare function getFlickerPreventionScript(timeout?: number): string;
|
|
1031
|
+
|
|
1032
|
+
/**
|
|
1033
|
+
* Analytics utilities for parsing and extracting data from events
|
|
1034
|
+
*/
|
|
1035
|
+
/**
|
|
1036
|
+
* Sanitize string values to prevent XSS
|
|
1037
|
+
*/
|
|
1038
|
+
declare function sanitizeString(value: unknown): string;
|
|
1039
|
+
/**
|
|
1040
|
+
* Round number to 2 decimal places
|
|
1041
|
+
*/
|
|
1042
|
+
declare function roundToTwo(value: unknown): number | null;
|
|
1043
|
+
/**
|
|
1044
|
+
* Extract product ID from Shopify GID
|
|
1045
|
+
*/
|
|
1046
|
+
declare function extractProductId(gid: string | undefined): string | null;
|
|
1047
|
+
/**
|
|
1048
|
+
* Extract product variant ID from Shopify GID
|
|
1049
|
+
*/
|
|
1050
|
+
declare function extractProductVariantId(gid: string | undefined): string | null;
|
|
1051
|
+
/**
|
|
1052
|
+
* Extract cart token from Shopify GID
|
|
1053
|
+
*/
|
|
1054
|
+
declare function extractCartToken(gid: string | undefined | null): string | null;
|
|
1055
|
+
/**
|
|
1056
|
+
* Clean cart token by removing query parameters
|
|
1057
|
+
*/
|
|
1058
|
+
declare function cleanCartToken(cartToken: string | null | undefined): string | null;
|
|
1059
|
+
/**
|
|
1060
|
+
* Check if Facebook or Instagram browser
|
|
1061
|
+
*/
|
|
1062
|
+
declare function checkFacebookInstagramBrowser(userAgent: string): boolean;
|
|
1063
|
+
/**
|
|
1064
|
+
* Parse and extract analytics view data from referrer, entry page, and user agent
|
|
1065
|
+
*/
|
|
1066
|
+
interface ParsedViewData {
|
|
1067
|
+
referrer_source: string;
|
|
1068
|
+
browser_info: string;
|
|
1069
|
+
os_info: string;
|
|
1070
|
+
device_type: string;
|
|
1071
|
+
page_entry_path: string;
|
|
1072
|
+
utm_medium: string;
|
|
1073
|
+
utm_source: string;
|
|
1074
|
+
utm_campaign: string;
|
|
1075
|
+
utm_content: string;
|
|
1076
|
+
utm_term: string;
|
|
1077
|
+
referrer_url: string;
|
|
1078
|
+
gclid: string;
|
|
1079
|
+
fbclid: string;
|
|
1080
|
+
pins_campaign_id: string;
|
|
1081
|
+
epik: string;
|
|
100
1082
|
}
|
|
101
|
-
declare function
|
|
102
|
-
|
|
1083
|
+
declare function parseAddViewData(params: {
|
|
1084
|
+
referrer?: string;
|
|
1085
|
+
entryPage?: string;
|
|
1086
|
+
userAgent?: string;
|
|
1087
|
+
}): ParsedViewData;
|
|
1088
|
+
/**
|
|
1089
|
+
* Get page type from pathname
|
|
1090
|
+
*/
|
|
1091
|
+
declare function getPageTypeFromPathname(path: string, hasLocalizedPaths?: boolean): string;
|
|
1092
|
+
/**
|
|
1093
|
+
* Check if visitor ID is in URL params
|
|
1094
|
+
*/
|
|
1095
|
+
declare function checkVisitorIdParams(searchParams: string): string | false;
|
|
1096
|
+
/**
|
|
1097
|
+
* Get user agent string without browser info
|
|
1098
|
+
* Used for more consistent user fingerprinting
|
|
1099
|
+
*/
|
|
1100
|
+
declare function getUserAgentNoBrowser(userAgent: string): string;
|
|
1101
|
+
|
|
1102
|
+
/**
|
|
1103
|
+
* Shopify-specific utilities
|
|
1104
|
+
*/
|
|
1105
|
+
/**
|
|
1106
|
+
* Extract numeric ID from a Shopify Global ID (GID).
|
|
1107
|
+
*
|
|
1108
|
+
* Shopify uses GIDs like "gid://shopify/Product/123456789" or "gid://shopify/ProductVariant/987654321".
|
|
1109
|
+
* This utility extracts the numeric ID portion.
|
|
1110
|
+
*
|
|
1111
|
+
* @param gid - Shopify Global ID or numeric ID string
|
|
1112
|
+
* @returns The numeric ID portion (e.g., "123456789")
|
|
1113
|
+
*
|
|
1114
|
+
* @example
|
|
1115
|
+
* ```ts
|
|
1116
|
+
* extractShopifyId("gid://shopify/Product/123456789"); // "123456789"
|
|
1117
|
+
* extractShopifyId("gid://shopify/ProductVariant/987654321"); // "987654321"
|
|
1118
|
+
* extractShopifyId("gid://shopify/Cart/abc123"); // "abc123"
|
|
1119
|
+
* extractShopifyId("123456789"); // "123456789" (already numeric)
|
|
1120
|
+
* ```
|
|
1121
|
+
*/
|
|
1122
|
+
declare function extractShopifyId(gid: string | null | undefined): string;
|
|
1123
|
+
/**
|
|
1124
|
+
* Extract the resource type from a Shopify Global ID.
|
|
1125
|
+
*
|
|
1126
|
+
* @param gid - Shopify Global ID
|
|
1127
|
+
* @returns The resource type (e.g., "Product", "ProductVariant", "Cart")
|
|
1128
|
+
*
|
|
1129
|
+
* @example
|
|
1130
|
+
* ```ts
|
|
1131
|
+
* extractShopifyType("gid://shopify/Product/123"); // "Product"
|
|
1132
|
+
* extractShopifyType("gid://shopify/ProductVariant/456"); // "ProductVariant"
|
|
1133
|
+
* extractShopifyType("123456789"); // null (not a GID)
|
|
1134
|
+
* ```
|
|
1135
|
+
*/
|
|
1136
|
+
declare function extractShopifyType(gid: string | null | undefined): string | null;
|
|
1137
|
+
/**
|
|
1138
|
+
* Check if a string is a Shopify Global ID.
|
|
1139
|
+
*
|
|
1140
|
+
* @param value - String to check
|
|
1141
|
+
* @returns True if it's a GID
|
|
1142
|
+
*
|
|
1143
|
+
* @example
|
|
1144
|
+
* ```ts
|
|
1145
|
+
* isShopifyGid("gid://shopify/Product/123"); // true
|
|
1146
|
+
* isShopifyGid("123456789"); // false
|
|
1147
|
+
* ```
|
|
1148
|
+
*/
|
|
1149
|
+
declare function isShopifyGid(value: string | null | undefined): boolean;
|
|
1150
|
+
/**
|
|
1151
|
+
* Try to detect the shop currency from Shopify's global object.
|
|
1152
|
+
* Only works on Shopify theme stores, not headless.
|
|
1153
|
+
*
|
|
1154
|
+
* @returns Currency code (e.g., "USD") or undefined
|
|
1155
|
+
*/
|
|
1156
|
+
declare function detectShopifyCurrency(): string | undefined;
|
|
1157
|
+
|
|
1158
|
+
/**
|
|
1159
|
+
* Cart attribute utilities for tagging carts with A/B test data
|
|
1160
|
+
*
|
|
1161
|
+
* These functions update Shopify cart attributes with test assignment data,
|
|
1162
|
+
* enabling order attribution for A/B test analysis.
|
|
1163
|
+
*/
|
|
1164
|
+
|
|
1165
|
+
/**
|
|
1166
|
+
* Get cart attributes payload from current test assignments
|
|
1167
|
+
* Returns an array of key-value pairs ready to be sent to Shopify
|
|
1168
|
+
*
|
|
1169
|
+
* @example
|
|
1170
|
+
* ```ts
|
|
1171
|
+
* const attributes = getCartAttributesPayload();
|
|
1172
|
+
* // Use with your own Storefront client
|
|
1173
|
+
* await storefront.mutate(CART_ATTRIBUTES_UPDATE_MUTATION, {
|
|
1174
|
+
* variables: { cartId, attributes }
|
|
1175
|
+
* });
|
|
1176
|
+
* ```
|
|
1177
|
+
*/
|
|
1178
|
+
declare function getCartAttributesPayload(): CartAttributeInput[];
|
|
1179
|
+
/**
|
|
1180
|
+
* Update cart attributes with test assignment data
|
|
1181
|
+
*
|
|
1182
|
+
* This function calls the Shopify Storefront API to update cart attributes.
|
|
1183
|
+
*
|
|
1184
|
+
* ## Authentication
|
|
1185
|
+
*
|
|
1186
|
+
* **For Hydrogen stores:** Use your storefront client directly with `getCartAttributesPayload()`
|
|
1187
|
+
*
|
|
1188
|
+
* **For Next.js/Other stores:** Pass the `storefrontAccessToken` option.
|
|
1189
|
+
*
|
|
1190
|
+
* ✅ The Storefront Access Token is **safe to use client-side**.
|
|
1191
|
+
* It's a public token designed by Shopify for browser use.
|
|
1192
|
+
* It can only read products and manage carts - it CANNOT delete products,
|
|
1193
|
+
* access admin functions, or do anything destructive.
|
|
1194
|
+
*
|
|
1195
|
+
* Get your token from: Shopify Admin → Settings → Apps → Develop apps
|
|
1196
|
+
*
|
|
1197
|
+
* @param cartId - The cart ID (GID or token, e.g., "gid://shopify/Cart/abc123" or just "abc123")
|
|
1198
|
+
* @param options - Configuration options including storefrontAccessToken
|
|
1199
|
+
* @returns Promise with success status and optional error message
|
|
1200
|
+
*
|
|
1201
|
+
* @example
|
|
1202
|
+
* ```ts
|
|
1203
|
+
* // Next.js usage - token is safe to use client-side!
|
|
1204
|
+
* const result = await updateCartAttributes(cartId, {
|
|
1205
|
+
* storefrontAccessToken: process.env.NEXT_PUBLIC_STOREFRONT_TOKEN
|
|
1206
|
+
* });
|
|
1207
|
+
*
|
|
1208
|
+
* if (!result.success) {
|
|
1209
|
+
* console.error('Failed to update cart attributes:', result.error);
|
|
1210
|
+
* }
|
|
1211
|
+
* ```
|
|
1212
|
+
*/
|
|
1213
|
+
declare function updateCartAttributes(cartId: string, options?: CartAttributesOptions): Promise<{
|
|
1214
|
+
success: boolean;
|
|
1215
|
+
error?: string;
|
|
1216
|
+
}>;
|
|
1217
|
+
/**
|
|
1218
|
+
* Cleanup/remove cart attributes
|
|
1219
|
+
* Sets all Elevate attributes to empty strings
|
|
1220
|
+
*
|
|
1221
|
+
* @param cartId - The cart ID (GID or token)
|
|
1222
|
+
* @param options - Configuration options including storefrontAccessToken
|
|
1223
|
+
*/
|
|
1224
|
+
declare function cleanupCartAttributes(cartId: string, options?: CartAttributesOptions): Promise<{
|
|
1225
|
+
success: boolean;
|
|
1226
|
+
error?: string;
|
|
1227
|
+
}>;
|
|
1228
|
+
|
|
1229
|
+
/**
|
|
1230
|
+
* GraphQL mutations for cart attributes
|
|
1231
|
+
*/
|
|
1232
|
+
/**
|
|
1233
|
+
* GraphQL mutation for updating cart attributes
|
|
1234
|
+
* Use this in your Storefront API calls
|
|
1235
|
+
*/
|
|
1236
|
+
declare const CART_ATTRIBUTES_UPDATE_MUTATION = "#graphql\n mutation cartAttributesUpdate($cartId: ID!, $attributes: [AttributeInput!]!) {\n cartAttributesUpdate(cartId: $cartId, attributes: $attributes) {\n cart {\n id\n attributes {\n key\n value\n }\n }\n userErrors {\n field\n message\n }\n }\n }\n";
|
|
1237
|
+
|
|
1238
|
+
/**
|
|
1239
|
+
* Manual tracking functions for non-Hydrogen frameworks (Next.js, etc.)
|
|
1240
|
+
*
|
|
1241
|
+
* Initialize once with initAnalytics(), then call tracking functions without params:
|
|
1242
|
+
*
|
|
1243
|
+
* @example
|
|
1244
|
+
* ```tsx
|
|
1245
|
+
* // In your layout/provider (once)
|
|
1246
|
+
* initAnalytics({
|
|
1247
|
+
* storeId: 'your-store.myshopify.com',
|
|
1248
|
+
* storefrontAccessToken: 'your-token',
|
|
1249
|
+
* });
|
|
1250
|
+
*
|
|
1251
|
+
* // Then anywhere in your app (no params needed)
|
|
1252
|
+
* trackPageView();
|
|
1253
|
+
* trackAddToCart({ cartId, productId, ... });
|
|
1254
|
+
* ```
|
|
1255
|
+
*/
|
|
1256
|
+
|
|
1257
|
+
interface AnalyticsConfig {
|
|
1258
|
+
storeId: string;
|
|
1259
|
+
storefrontAccessToken?: string;
|
|
1260
|
+
hasLocalizedPaths?: boolean;
|
|
1261
|
+
workerUrl?: string;
|
|
1262
|
+
ordersWorkerUrl?: string;
|
|
1263
|
+
}
|
|
1264
|
+
/**
|
|
1265
|
+
* Initialize analytics config once. Call this in your app's entry point or layout.
|
|
1266
|
+
* After init, tracking functions don't need storeId/token params.
|
|
1267
|
+
*
|
|
1268
|
+
* @example
|
|
1269
|
+
* ```tsx
|
|
1270
|
+
* // In _app.tsx or layout.tsx
|
|
1271
|
+
* initAnalytics({
|
|
1272
|
+
* storeId: 'your-store.myshopify.com',
|
|
1273
|
+
* storefrontAccessToken: process.env.NEXT_PUBLIC_STOREFRONT_TOKEN,
|
|
1274
|
+
* });
|
|
1275
|
+
* ```
|
|
1276
|
+
*/
|
|
1277
|
+
declare function initAnalytics(config: AnalyticsConfig): void;
|
|
1278
|
+
/**
|
|
1279
|
+
* Track page view event
|
|
1280
|
+
* Call this on route changes or in useEffect
|
|
1281
|
+
*
|
|
1282
|
+
* @example After initAnalytics()
|
|
1283
|
+
* ```ts
|
|
1284
|
+
* await trackPageView(); // No params needed!
|
|
1285
|
+
* ```
|
|
1286
|
+
*
|
|
1287
|
+
* @example Without init (pass params)
|
|
1288
|
+
* ```ts
|
|
1289
|
+
* await trackPageView({ storeId: "mystore.myshopify.com" });
|
|
1290
|
+
* ```
|
|
1291
|
+
*/
|
|
1292
|
+
declare function trackPageView(params?: Partial<TrackPageViewParams>): Promise<void>;
|
|
1293
|
+
/**
|
|
1294
|
+
* Track product view event
|
|
1295
|
+
* Call this on product pages
|
|
1296
|
+
*
|
|
1297
|
+
* @example After initAnalytics()
|
|
1298
|
+
* ```ts
|
|
1299
|
+
* await trackProductView({ productId: "123", productPrice: 99.99 });
|
|
1300
|
+
* ```
|
|
1301
|
+
*/
|
|
1302
|
+
declare function trackProductView(params: Omit<TrackProductViewParams, "storeId"> & {
|
|
1303
|
+
storeId?: string;
|
|
1304
|
+
}): Promise<void>;
|
|
1305
|
+
/**
|
|
1306
|
+
* Track add to cart event
|
|
1307
|
+
* Call this when user clicks "Add to Cart"
|
|
1308
|
+
*
|
|
1309
|
+
* Cart attributes are automatically updated for order attribution if
|
|
1310
|
+
* storefrontAccessToken was provided to initAnalytics() or passed here.
|
|
1311
|
+
*
|
|
1312
|
+
* @example After initAnalytics()
|
|
1313
|
+
* ```ts
|
|
1314
|
+
* await trackAddToCart({
|
|
1315
|
+
* cartId: "gid://shopify/Cart/abc123",
|
|
1316
|
+
* productId: "123456789",
|
|
1317
|
+
* variantId: "987654321",
|
|
1318
|
+
* productPrice: 99.99,
|
|
1319
|
+
* productQuantity: 1,
|
|
1320
|
+
* });
|
|
1321
|
+
* ```
|
|
1322
|
+
*/
|
|
1323
|
+
declare function trackAddToCart(params: Omit<TrackAddToCartParams, "storeId" | "storefrontAccessToken"> & {
|
|
1324
|
+
storeId?: string;
|
|
1325
|
+
storefrontAccessToken?: string;
|
|
1326
|
+
}): Promise<void>;
|
|
1327
|
+
/**
|
|
1328
|
+
* Track remove from cart event
|
|
1329
|
+
* Call this when user removes item from cart
|
|
1330
|
+
*/
|
|
1331
|
+
declare function trackRemoveFromCart(params: Omit<TrackRemoveFromCartParams, "storeId"> & {
|
|
1332
|
+
storeId?: string;
|
|
1333
|
+
}): Promise<void>;
|
|
1334
|
+
/**
|
|
1335
|
+
* Track cart view event
|
|
1336
|
+
* Call this when user views cart page
|
|
1337
|
+
*/
|
|
1338
|
+
declare function trackCartView(params: Omit<TrackCartViewParams, "storeId"> & {
|
|
1339
|
+
storeId?: string;
|
|
1340
|
+
}): Promise<void>;
|
|
1341
|
+
/**
|
|
1342
|
+
* Track search submitted event
|
|
1343
|
+
* Call this when user submits a search
|
|
1344
|
+
*
|
|
1345
|
+
* @example After initAnalytics()
|
|
1346
|
+
* ```ts
|
|
1347
|
+
* await trackSearchSubmitted({ searchQuery: "running shoes" });
|
|
1348
|
+
* ```
|
|
1349
|
+
*
|
|
1350
|
+
* @example Without init (pass params)
|
|
1351
|
+
* ```ts
|
|
1352
|
+
* await trackSearchSubmitted({
|
|
1353
|
+
* storeId: "mystore.myshopify.com",
|
|
1354
|
+
* searchQuery: "running shoes",
|
|
1355
|
+
* currency: "USD"
|
|
1356
|
+
* });
|
|
1357
|
+
* ```
|
|
1358
|
+
*/
|
|
1359
|
+
declare function trackSearchSubmitted(params: Omit<TrackSearchSubmittedParams, "storeId"> & {
|
|
1360
|
+
storeId?: string;
|
|
1361
|
+
}): Promise<void>;
|
|
1362
|
+
/**
|
|
1363
|
+
* Track checkout started event
|
|
1364
|
+
* Call this when user starts checkout
|
|
1365
|
+
*
|
|
1366
|
+
* @example After initAnalytics()
|
|
1367
|
+
* ```ts
|
|
1368
|
+
* await trackCheckoutStarted({
|
|
1369
|
+
* cartTotalPrice: 109.98,
|
|
1370
|
+
* cartItems: [...],
|
|
1371
|
+
* });
|
|
1372
|
+
* ```
|
|
1373
|
+
*/
|
|
1374
|
+
declare function trackCheckoutStarted(params: Omit<TrackCheckoutStartedParams, "storeId"> & {
|
|
1375
|
+
storeId?: string;
|
|
1376
|
+
}): Promise<void>;
|
|
1377
|
+
/**
|
|
1378
|
+
* Track checkout completed event (order placed)
|
|
1379
|
+
* Call this when order is placed
|
|
1380
|
+
*
|
|
1381
|
+
* NOTE: This sends to a different endpoint (orders worker)
|
|
1382
|
+
*
|
|
1383
|
+
* @example After initAnalytics()
|
|
1384
|
+
* ```ts
|
|
1385
|
+
* await trackCheckoutCompleted({
|
|
1386
|
+
* orderId: "order_123456",
|
|
1387
|
+
* cartTotalPrice: 109.98,
|
|
1388
|
+
* cartItems: [...],
|
|
1389
|
+
* });
|
|
1390
|
+
* ```
|
|
1391
|
+
*/
|
|
1392
|
+
declare function trackCheckoutCompleted(params: Omit<TrackCheckoutCompletedParams, "storeId"> & {
|
|
1393
|
+
storeId?: string;
|
|
1394
|
+
}): Promise<void>;
|
|
1395
|
+
/**
|
|
1396
|
+
* Hook for automatic page view tracking on route changes
|
|
1397
|
+
* Use in Next.js app router or any React app
|
|
1398
|
+
*
|
|
1399
|
+
* NOTE: For Next.js App Router, consider using this with `usePathname()`:
|
|
1400
|
+
* ```tsx
|
|
1401
|
+
* const pathname = usePathname();
|
|
1402
|
+
* usePageViewTracking({ pathname, enabled: true });
|
|
1403
|
+
* ```
|
|
1404
|
+
*
|
|
1405
|
+
* @example Basic usage (tracks on mount only)
|
|
1406
|
+
* ```tsx
|
|
1407
|
+
* function Layout({ children }) {
|
|
1408
|
+
* usePageViewTracking({ enabled: true });
|
|
1409
|
+
* return <>{children}</>;
|
|
1410
|
+
* }
|
|
1411
|
+
* ```
|
|
1412
|
+
*
|
|
1413
|
+
* @example With Next.js usePathname (tracks on route changes)
|
|
1414
|
+
* ```tsx
|
|
1415
|
+
* import { usePathname } from 'next/navigation';
|
|
1416
|
+
*
|
|
1417
|
+
* function Layout({ children }) {
|
|
1418
|
+
* const pathname = usePathname();
|
|
1419
|
+
* usePageViewTracking({ pathname, enabled: true });
|
|
1420
|
+
* return <>{children}</>;
|
|
1421
|
+
* }
|
|
1422
|
+
* ```
|
|
1423
|
+
*/
|
|
1424
|
+
declare function usePageViewTracking(params: UsePageViewTrackingParams & {
|
|
1425
|
+
pathname?: string;
|
|
1426
|
+
}): void;
|
|
1427
|
+
|
|
1428
|
+
interface UseExperimentResult {
|
|
1429
|
+
/** The full variant object (null if not assigned) */
|
|
103
1430
|
variant: Variation | null;
|
|
1431
|
+
/** True while loading config */
|
|
104
1432
|
isLoading: boolean;
|
|
105
|
-
|
|
1433
|
+
/** True if assigned to control group */
|
|
1434
|
+
isControl: boolean;
|
|
1435
|
+
/** True if assigned to variation A (first non-control) */
|
|
1436
|
+
isA: boolean;
|
|
1437
|
+
/** True if assigned to variation B (second non-control) */
|
|
1438
|
+
isB: boolean;
|
|
1439
|
+
/** True if assigned to variation C (third non-control) */
|
|
1440
|
+
isC: boolean;
|
|
1441
|
+
/** True if assigned to variation D (fourth non-control) */
|
|
1442
|
+
isD: boolean;
|
|
1443
|
+
}
|
|
1444
|
+
/**
|
|
1445
|
+
* Hook to get assigned variant for a test
|
|
1446
|
+
*
|
|
1447
|
+
* @example
|
|
1448
|
+
* ```tsx
|
|
1449
|
+
* const { isControl, isA, isB } = useExperiment('my-test');
|
|
1450
|
+
*
|
|
1451
|
+
* if (isControl) return <Original />;
|
|
1452
|
+
* if (isA) return <VariantA />;
|
|
1453
|
+
* if (isB) return <VariantB />;
|
|
1454
|
+
* ```
|
|
1455
|
+
*/
|
|
1456
|
+
declare function useExperiment(testId: string): UseExperimentResult;
|
|
106
1457
|
|
|
107
|
-
|
|
1458
|
+
interface ElevateProviderSimpleProps {
|
|
1459
|
+
/** Shopify store domain (e.g., "your-store.myshopify.com") */
|
|
1460
|
+
storeId: string;
|
|
1461
|
+
/**
|
|
1462
|
+
* Storefront Access Token - Required for cart attribute tracking (order attribution)
|
|
1463
|
+
*
|
|
1464
|
+
* This is SAFE to use client-side - it's a public token with limited permissions.
|
|
1465
|
+
* Get it from: Shopify Admin → Settings → Apps → Develop apps
|
|
1466
|
+
*
|
|
1467
|
+
* Without this token, A/B tests work but orders won't be attributed to variants.
|
|
1468
|
+
*/
|
|
1469
|
+
storefrontAccessToken?: string;
|
|
1470
|
+
/**
|
|
1471
|
+
* Enable flicker prevention - hides content until test assignment is complete
|
|
1472
|
+
* Prevents users from seeing content flash/change when variants load
|
|
1473
|
+
* @default false
|
|
1474
|
+
*/
|
|
1475
|
+
preventFlickering?: boolean;
|
|
1476
|
+
/**
|
|
1477
|
+
* Timeout in milliseconds for flicker prevention failsafe
|
|
1478
|
+
* Content will show after this time even if assignment isn't complete
|
|
1479
|
+
* @default 3000
|
|
1480
|
+
*/
|
|
1481
|
+
flickerTimeout?: number;
|
|
1482
|
+
children: React.ReactNode;
|
|
1483
|
+
}
|
|
1484
|
+
/**
|
|
1485
|
+
* ElevateProvider - Provides A/B test configuration to child components
|
|
1486
|
+
*
|
|
1487
|
+
* @example Next.js / Remix
|
|
1488
|
+
* ```tsx
|
|
1489
|
+
* <ElevateProvider
|
|
1490
|
+
* storeId="your-store.myshopify.com"
|
|
1491
|
+
* storefrontAccessToken="your-public-token"
|
|
1492
|
+
* >
|
|
1493
|
+
* <App />
|
|
1494
|
+
* </ElevateProvider>
|
|
1495
|
+
* ```
|
|
1496
|
+
*
|
|
1497
|
+
* @example Hydrogen (with Analytics.Provider)
|
|
1498
|
+
* ```tsx
|
|
1499
|
+
* <Analytics.Provider cart={cart} shop={shop} consent={consent}>
|
|
1500
|
+
* <ElevateProvider storeId="your-store.myshopify.com" storefrontAccessToken="token">
|
|
1501
|
+
* <ElevateAnalytics />
|
|
1502
|
+
* <App />
|
|
1503
|
+
* </ElevateProvider>
|
|
1504
|
+
* </Analytics.Provider>
|
|
1505
|
+
* ```
|
|
1506
|
+
*/
|
|
1507
|
+
declare function ElevateProvider({ storeId, storefrontAccessToken, preventFlickering, flickerTimeout, children, }: ElevateProviderSimpleProps): React.JSX.Element;
|
|
108
1508
|
|
|
109
1509
|
/**
|
|
110
1510
|
* Hook to access Elevate config from context
|
|
111
1511
|
*/
|
|
112
1512
|
declare function useElevateConfig(): ElevateContextValue;
|
|
113
1513
|
|
|
114
|
-
declare const VERSION = "1.1.
|
|
1514
|
+
declare const VERSION = "1.1.2";
|
|
115
1515
|
declare const DEFAULT_CONFIG: {
|
|
116
1516
|
enabled: boolean;
|
|
117
1517
|
trackingEndpoint: string;
|
|
118
1518
|
cacheDuration: number;
|
|
119
1519
|
};
|
|
120
1520
|
|
|
121
|
-
export { type BackendConfig, DEFAULT_CONFIG, type ElevateConfig, type ElevateContextValue, ElevateProvider, type ElevateProviderProps,
|
|
1521
|
+
export { type BackendConfig, type BackendTest, type BackendVariation, type BaseTrackingConfig, CART_ATTRIBUTES_UPDATE_MUTATION, COUNTRIES, type CartAttributeInput, type CartAttributesOptions, type CartItemInput, type CartItemPayload, DEFAULT_CONFIG, type ElevateAnalyticsProps, type ElevateConfig, type ElevateContextValue, ElevateProvider, type ElevateProviderProps, type EventPayload, type ExperimentStatus, type GeoLocation, type NoteAttribute, type ParsedViewData, type PreviewState, REGIONS, type Test, type TestAssignment, type TrackAddToCartParams, type TrackCartViewParams, type TrackCheckoutCompletedParams, type TrackCheckoutStartedParams, type TrackPageViewParams, type TrackProductViewParams, type TrackRemoveFromCartParams, type TrackSearchSubmittedParams, type TrackingEvent, type UseExperimentResult, type UsePageViewTrackingParams, VERSION, type Variation, assignAndPersistVariant, assignVariant, buildEabTestsParam, calculateRevenueLift, checkFacebookBrowser, checkFacebookInstagramBrowser, checkInstagramBrowser, checkPinterestBrowser, checkTikTokBrowser, checkVisitorIdParams, cleanCartToken, cleanupCartAttributes, cleanupFlickerPrevention, clearPreviewMode, deleteCookie, detectShopifyCurrency, extractCartToken, extractProductId, extractProductVariantId, extractShopifyId, extractShopifyType, generateExperimentId, getAssignedVariant, getCartAttributesPayload, getCookie, getCountryCode, getDeviceType, getFlickerPreventionScript, getGeoLocation, getJsonCookie, getJsonSessionItem, getPageTypeFromPathname, getPreviewState, getPreviewVariation, getReferrerData, getSessionId, getSessionItem, getTestList, getTrafficSource, getUserAgentNoBrowser, getVisitorId, hasSessionView, hasUniqueView, hashString, hideForFlicker, initAnalytics, initializeSessionId, initializeVisitorId, injectFlickerStyles, isCountryExcluded, isCountryIncluded, isFlickerPreventionActive, isInPreviewMode, isPreviewTest, isShopifyGid, matchesGeoTargeting, parseAddViewData, revealAfterFlicker, roundToTwo, sanitizeString, saveTestList, setCookie, setCountryCode, setGeoLocation, setReferrerData, setSessionItem, setupFlickerPrevention, shouldShowTest, trackAddToCart, trackCartView, trackCheckoutCompleted, trackCheckoutStarted, trackPageView, trackProductView, trackRemoveFromCart, trackSearchSubmitted, trackSessionView, trackUniqueView, trackViews, updateCartAttributes, updateUrlWithTestParams, useElevateConfig, useExperiment, usePageViewTracking, uuidv4, validateConfig };
|