@elevateab/sdk 1.4.8 → 1.4.10
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 +76 -31
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,6 +9,7 @@ npm install @elevateab/sdk
|
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
**Peer Dependencies:**
|
|
12
|
+
|
|
12
13
|
- `react` >= 18.0.0 or >= 19.0.0
|
|
13
14
|
- `@shopify/hydrogen` >= 2023.10.0 (Hydrogen only)
|
|
14
15
|
- `next` >= 13.0.0 (Next.js only)
|
|
@@ -19,22 +20,57 @@ npm install @elevateab/sdk
|
|
|
19
20
|
|
|
20
21
|
Hydrogen uses automatic analytics tracking via Shopify's `useAnalytics()` hook.
|
|
21
22
|
|
|
23
|
+
### 1. Content Security Policy (CSP) Setup (first)
|
|
24
|
+
|
|
25
|
+
If your store uses a strict CSP, allow Elevate domains before wiring the provider.
|
|
26
|
+
|
|
27
|
+
```tsx
|
|
28
|
+
// app/entry.server.tsx
|
|
29
|
+
import { createContentSecurityPolicy } from "@shopify/hydrogen";
|
|
30
|
+
|
|
31
|
+
const { nonce, header, NonceProvider } = createContentSecurityPolicy({
|
|
32
|
+
shop: {
|
|
33
|
+
checkoutDomain: context.env.PUBLIC_CHECKOUT_DOMAIN,
|
|
34
|
+
storeDomain: context.env.PUBLIC_STORE_DOMAIN,
|
|
35
|
+
},
|
|
36
|
+
scriptSrc: [
|
|
37
|
+
"'self'",
|
|
38
|
+
"https://cdn.shopify.com",
|
|
39
|
+
"https://ds0wlyksfn0sb.cloudfront.net",
|
|
40
|
+
],
|
|
41
|
+
connectSrc: [
|
|
42
|
+
"https://ds0wlyksfn0sb.cloudfront.net",
|
|
43
|
+
"https://bitter-river-9c62.support-67d.workers.dev",
|
|
44
|
+
"https://d339co84ntxcme.cloudfront.net",
|
|
45
|
+
"https://configs.elevateab.com",
|
|
46
|
+
],
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### 2. Add Elevate Provider + Hydrogen Analytics
|
|
51
|
+
|
|
22
52
|
```tsx
|
|
23
53
|
// app/root.tsx
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
54
|
+
import { Analytics, useNonce } from "@shopify/hydrogen";
|
|
55
|
+
import { ElevateProvider } from "@elevateab/sdk";
|
|
56
|
+
import { ElevateHydrogenAnalytics } from "@elevateab/sdk/hydrogen";
|
|
57
|
+
import { Outlet, useLoaderData } from "@remix-run/react";
|
|
26
58
|
|
|
27
59
|
export default function Root() {
|
|
28
60
|
const data = useLoaderData<typeof loader>();
|
|
61
|
+
const nonce = useNonce();
|
|
29
62
|
|
|
30
63
|
return (
|
|
31
64
|
<Analytics.Provider cart={data.cart} shop={data.shop} consent={data.consent}>
|
|
65
|
+
{/* ElevateProvider must be inside Analytics.Provider */}
|
|
32
66
|
<ElevateProvider
|
|
33
67
|
storeId="mystore.myshopify.com"
|
|
34
|
-
storefrontAccessToken={
|
|
68
|
+
storefrontAccessToken={data.consent?.storefrontAccessToken}
|
|
35
69
|
preventFlickering={true}
|
|
70
|
+
nonce={nonce}
|
|
36
71
|
>
|
|
37
|
-
|
|
72
|
+
{/* ElevateHydrogenAnalytics must be inside ElevateProvider */}
|
|
73
|
+
<ElevateHydrogenAnalytics />
|
|
38
74
|
<Outlet />
|
|
39
75
|
</ElevateProvider>
|
|
40
76
|
</Analytics.Provider>
|
|
@@ -76,6 +112,7 @@ export default function RootLayout({ children }) {
|
|
|
76
112
|
```
|
|
77
113
|
|
|
78
114
|
The `ElevateNextProvider` automatically:
|
|
115
|
+
|
|
79
116
|
- Tracks page views on route changes
|
|
80
117
|
- Initializes analytics globally
|
|
81
118
|
- Prevents content flicker (when `preventFlickering={true}`)
|
|
@@ -109,12 +146,12 @@ import { trackAddToCart } from "@elevateab/sdk";
|
|
|
109
146
|
async function handleAddToCart() {
|
|
110
147
|
// Shopify GIDs are automatically converted to numeric IDs
|
|
111
148
|
await trackAddToCart({
|
|
112
|
-
productId: product.id,
|
|
113
|
-
variantId: variant.id,
|
|
149
|
+
productId: product.id, // "gid://shopify/Product/123" works
|
|
150
|
+
variantId: variant.id, // "gid://shopify/ProductVariant/456" works
|
|
114
151
|
productPrice: 99.99,
|
|
115
152
|
productQuantity: 1,
|
|
116
153
|
currency: "USD",
|
|
117
|
-
cartId: cart.id,
|
|
154
|
+
cartId: cart.id, // For cart attribute tagging
|
|
118
155
|
});
|
|
119
156
|
}
|
|
120
157
|
```
|
|
@@ -144,7 +181,12 @@ await trackCartView({
|
|
|
144
181
|
cartTotalQuantity: 2,
|
|
145
182
|
currency: "USD",
|
|
146
183
|
cartItems: [
|
|
147
|
-
{
|
|
184
|
+
{
|
|
185
|
+
productId: "123",
|
|
186
|
+
variantId: "456",
|
|
187
|
+
productPrice: 99.99,
|
|
188
|
+
productQuantity: 1,
|
|
189
|
+
},
|
|
148
190
|
],
|
|
149
191
|
});
|
|
150
192
|
|
|
@@ -156,7 +198,9 @@ await trackSearchSubmitted({ searchQuery: "blue shirt" });
|
|
|
156
198
|
|
|
157
199
|
## Using A/B Tests
|
|
158
200
|
|
|
159
|
-
### useExperiment Hook
|
|
201
|
+
### useExperiment Hook (optional)
|
|
202
|
+
|
|
203
|
+
> **Note:** `useExperiment` is only needed if you want to write conditional logic in your components based on which variant a user is in. Most test types (content, custom code, split URL, price) run automatically — you don't need this hook for those.
|
|
160
204
|
|
|
161
205
|
```tsx
|
|
162
206
|
import { useExperiment } from "@elevateab/sdk";
|
|
@@ -169,7 +213,7 @@ function PricingSection() {
|
|
|
169
213
|
if (variant?.isControl) {
|
|
170
214
|
return <Price amount={99.99} />;
|
|
171
215
|
}
|
|
172
|
-
|
|
216
|
+
|
|
173
217
|
return <Price amount={79.99} />;
|
|
174
218
|
}
|
|
175
219
|
```
|
|
@@ -179,13 +223,13 @@ function PricingSection() {
|
|
|
179
223
|
```tsx
|
|
180
224
|
const { variant } = useExperiment("test-id");
|
|
181
225
|
|
|
182
|
-
variant?.isControl
|
|
183
|
-
variant?.isA
|
|
184
|
-
variant?.isB
|
|
185
|
-
variant?.isC
|
|
186
|
-
variant?.isD
|
|
187
|
-
variant?.id
|
|
188
|
-
variant?.name
|
|
226
|
+
variant?.isControl; // true if control group
|
|
227
|
+
variant?.isA; // true if variant A
|
|
228
|
+
variant?.isB; // true if variant B
|
|
229
|
+
variant?.isC; // true if variant C
|
|
230
|
+
variant?.isD; // true if variant D
|
|
231
|
+
variant?.id; // variant ID
|
|
232
|
+
variant?.name; // variant name
|
|
189
233
|
```
|
|
190
234
|
|
|
191
235
|
### Multiple Variants
|
|
@@ -213,6 +257,7 @@ https://yourstore.com/?eabUserPreview=true&abtid=<test-id>&eab_tests=<short-id>_
|
|
|
213
257
|
```
|
|
214
258
|
|
|
215
259
|
Example:
|
|
260
|
+
|
|
216
261
|
```
|
|
217
262
|
https://yourstore.com/products/shirt?eabUserPreview=true&abtid=abc123&eab_tests=c123_12345
|
|
218
263
|
```
|
|
@@ -265,7 +310,7 @@ The Storefront Access Token is safe to use client-side - it's a public token des
|
|
|
265
310
|
import { extractShopifyId, isShopifyGid } from "@elevateab/sdk";
|
|
266
311
|
|
|
267
312
|
extractShopifyId("gid://shopify/Product/123456"); // "123456"
|
|
268
|
-
isShopifyGid("gid://shopify/Product/123");
|
|
313
|
+
isShopifyGid("gid://shopify/Product/123"); // true
|
|
269
314
|
```
|
|
270
315
|
|
|
271
316
|
Note: Tracking functions automatically extract IDs, so you rarely need these directly.
|
|
@@ -278,25 +323,25 @@ Note: Tracking functions automatically extract IDs, so you rarely need these dir
|
|
|
278
323
|
|
|
279
324
|
```tsx
|
|
280
325
|
interface ElevateProviderProps {
|
|
281
|
-
storeId: string;
|
|
282
|
-
storefrontAccessToken?: string;
|
|
283
|
-
preventFlickering?: boolean;
|
|
284
|
-
flickerTimeout?: number;
|
|
326
|
+
storeId: string; // Required: your-store.myshopify.com
|
|
327
|
+
storefrontAccessToken?: string; // For cart attribute tagging
|
|
328
|
+
preventFlickering?: boolean; // Enable anti-flicker (default: false)
|
|
329
|
+
flickerTimeout?: number; // Max wait time in ms (default: 3000)
|
|
285
330
|
children: React.ReactNode;
|
|
286
331
|
}
|
|
287
332
|
```
|
|
288
333
|
|
|
289
334
|
### Analytics Events Summary
|
|
290
335
|
|
|
291
|
-
| Event
|
|
292
|
-
|
|
293
|
-
| Page view
|
|
294
|
-
| Product view
|
|
295
|
-
| Add to cart
|
|
296
|
-
| Remove from cart
|
|
297
|
-
| Cart view
|
|
298
|
-
| Search
|
|
299
|
-
| Checkout started
|
|
336
|
+
| Event | Hydrogen | Next.js |
|
|
337
|
+
| ------------------ | --------- | -------------------------- |
|
|
338
|
+
| Page view | Automatic | Automatic |
|
|
339
|
+
| Product view | Automatic | `ProductViewTracker` |
|
|
340
|
+
| Add to cart | Automatic | `trackAddToCart()` |
|
|
341
|
+
| Remove from cart | Automatic | `trackRemoveFromCart()` |
|
|
342
|
+
| Cart view | Automatic | `trackCartView()` |
|
|
343
|
+
| Search | Automatic | `trackSearchSubmitted()` |
|
|
344
|
+
| Checkout started | Automatic | `trackCheckoutStarted()` |
|
|
300
345
|
| Checkout completed | Automatic | `trackCheckoutCompleted()` |
|
|
301
346
|
|
|
302
347
|
---
|