@liquidcommerce/elements-sdk 2.6.0-beta.127 → 2.6.0-beta.129

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.
Files changed (33) hide show
  1. package/README.md +4 -2
  2. package/dist/index.checkout.esm.js +9281 -8938
  3. package/dist/index.esm.js +13165 -12814
  4. package/dist/ssr-stub.esm.js +1 -0
  5. package/dist/types/core/client/actions/client-analytics-action.service.d.ts +35 -0
  6. package/dist/types/core/client/actions/client-checkout-action.service.d.ts +1 -0
  7. package/dist/types/core/client/client-action.service.d.ts +1 -0
  8. package/dist/types/core/client/client-config.service.d.ts +2 -0
  9. package/dist/types/core/google-tag-manager.service.d.ts +3 -2
  10. package/dist/types/core/pubsub/interfaces/checkout.interface.d.ts +4 -0
  11. package/dist/types/core/pubsub/interfaces/core.interface.d.ts +2 -1
  12. package/dist/types/enums/core.enum.d.ts +1 -0
  13. package/dist/types/index.checkout.d.ts +3 -2
  14. package/dist/types/index.d.ts +1 -0
  15. package/dist/types/interfaces/analytics.interface.d.ts +41 -0
  16. package/dist/types/interfaces/client.interface.d.ts +5 -0
  17. package/dist/types/interfaces/config.interface.d.ts +1 -0
  18. package/dist/types/modules/cart/cart.commands.d.ts +3 -1
  19. package/dist/types/modules/checkout/checkout.commands.d.ts +8 -0
  20. package/dist/types/modules/checkout/components/checkout-express-checkout.component.d.ts +1 -0
  21. package/dist/types/modules/product-list/product-list.commands.d.ts +5 -0
  22. package/dist/types/ssr/stub.checkout.d.ts +2 -1
  23. package/dist/types/ssr/stub.d.ts +2 -1
  24. package/docs/v1/README.md +1 -0
  25. package/docs/v1/api/actions/analytics-actions.md +326 -0
  26. package/docs/v1/api/actions/checkout-actions.md +5 -2
  27. package/docs/v1/api/client.md +7 -2
  28. package/docs/v1/api/configuration.md +4 -0
  29. package/docs/v1/api/typescript-types.md +73 -1
  30. package/docs/v1/guides/checkout-component.md +14 -2
  31. package/docs/v1/guides/events.md +22 -1
  32. package/docs/v1/reference/analytics.md +52 -9
  33. package/package.json +1 -1
@@ -12,7 +12,8 @@ Checkout actions allow you to programmatically control the checkout flow.
12
12
  openCheckout(): void
13
13
  ```
14
14
 
15
- Opens the checkout drawer or navigates to checkout page.
15
+ Opens the checkout drawer or navigates to checkout page. Reports `begin_checkout` for the cart's items
16
+ to GTM, as the cart's own Checkout button does, unless the drawer already shows the checkout.
16
17
 
17
18
  ```javascript
18
19
  window.LiquidCommerce.elements.actions.checkout.openCheckout();
@@ -36,7 +37,7 @@ window.LiquidCommerce.elements.actions.checkout.closeCheckout();
36
37
  toggleCheckout(): void
37
38
  ```
38
39
 
39
- Toggles checkout open/closed.
40
+ Toggles checkout open/closed. Opening it reports `begin_checkout`, as `openCheckout()` does.
40
41
 
41
42
  ```javascript
42
43
  window.LiquidCommerce.elements.actions.checkout.toggleCheckout();
@@ -64,6 +65,8 @@ addProduct(params: IAddProductParams[], openCheckout?: boolean): Promise<void>
64
65
 
65
66
  Add products and open checkout in one call. Products are added to the cart (via the cart action, or directly when none is wired up), then checkout is prepared and opened. For a checkout without a cart session, use `addAnonymousProduct`.
66
67
 
68
+ Reports `add_to_cart` for the added products and then `begin_checkout` for the cart to GTM, so don't report either again with [`actions.analytics`](./analytics-actions.md).
69
+
67
70
  `IAddProductParams.engravingLines?: string[]` — optional engraving. Same rules as [`actions.cart.addProduct()`](./cart-actions.md#actionscartaddproduct): invalid input is ignored, blanks stripped, lines clamped to the product's `maxLines` / `maxCharsPerLine`, and engraving is dropped (without failing) when the product, variant, or fulfillment doesn't support it.
68
71
 
69
72
  ```javascript
@@ -64,8 +64,10 @@ const client = await ElementsCheckout('YOUR_API_KEY', {
64
64
  });
65
65
  ```
66
66
 
67
- The checkout-only client exposes `injectCheckout()`, `injectExpressCheckout()`, `actions.checkout`
68
- and `destroy()`.
67
+ The checkout-only client exposes `injectCheckout()`, `injectExpressCheckout()`, `actions.checkout`,
68
+ `actions.analytics` and `destroy()`. `actions.analytics` reports the steps your own UI renders —
69
+ product views, address, availability, starting checkout — to the same GTM stream the checkout
70
+ reports to; see [Analytics Actions](./actions/analytics-actions.md).
69
71
 
70
72
  #### injectExpressCheckout()
71
73
 
@@ -73,6 +75,9 @@ Injects only the Apple Pay and Google Pay wallet buttons, anywhere on the page,
73
75
  the checkout UI. Confirming the wallet sheet places the order outright — the wallet's contact and
74
76
  billing details are sent to the checkout, so the shopper never fills a checkout form.
75
77
 
78
+ Express checkout is off by default: pass `development.enableExpressCheckout: true` in the client config to show it. Without it this
79
+ method renders nothing and resolves to `null`.
80
+
76
81
  ```typescript
77
82
  injectExpressCheckout(params: IInjectExpressCheckoutParams): Promise<IInjectedComponent | null>
78
83
  ```
@@ -563,6 +563,7 @@ interface ILiquidCommerceElementsDevelopmentConfig {
563
563
  customApiUrl?: string;
564
564
  openShadowDom?: boolean;
565
565
  mockMode?: boolean;
566
+ enableExpressCheckout?: boolean;
566
567
  }
567
568
  ```
568
569
 
@@ -571,6 +572,9 @@ interface ILiquidCommerceElementsDevelopmentConfig {
571
572
  | `customApiUrl` | `string` | Custom API URL for local or custom backend testing |
572
573
  | `openShadowDom` | `boolean` | Use an OPEN (inspectable) Shadow DOM instead of the default closed mode, for debugging. Shadow DOM is always attached; forced off in production (default: `false`) |
573
574
  | `mockMode` | `boolean` | Enable mock mode to receive mock data from the API; sends an `X-Liquid-Api-Mock-Mode` header with all requests (default: `false`) |
575
+ | `enableExpressCheckout` | `boolean` | Show the Apple Pay / Google Pay express checkout and the checkout's delivery-method switch (same-day vs shipping) — the express block and delivery-method section in the checkout element, and `injectExpressCheckoutElement()` / `injectExpressCheckout()`, which otherwise render nothing and resolve to `null`. Honoured in every environment, production included (default: `false`) |
576
+
577
+ > **Temporary:** this flag exists only while express checkout and the delivery-method switch are being verified. Once they are confirmed, the flag will be removed and both will always be on.
574
578
 
575
579
  > To pre-select a payment method and skip the card form (in any environment), use [`actions.checkout.setSavedPaymentMethod`](./actions/checkout-actions.md#actionscheckoutsetsavedpaymentmethod) instead.
576
580
 
@@ -21,6 +21,8 @@ import { ElementsCheckout } from '@liquidcommerce/elements-sdk/checkout';
21
21
  import type {
22
22
  IElementsCheckoutClient,
23
23
  IElementsCheckoutActions,
24
+ IAnalyticsActions,
25
+ IAnalyticsItem,
24
26
  ILiquidCommerceElementsCheckoutClientConfig,
25
27
  IInjectedComponent
26
28
  } from '@liquidcommerce/elements-sdk/checkout';
@@ -81,7 +83,7 @@ Checkout-only client interface returned by `ElementsCheckout()`.
81
83
  interface IElementsCheckoutClient {
82
84
  injectCheckout(params: IInjectCheckoutParams): Promise<IInjectedComponent | null>;
83
85
  injectExpressCheckout(params: IInjectExpressCheckoutParams): Promise<IInjectedComponent | null>;
84
- actions: { checkout: IElementsCheckoutActions };
86
+ actions: { checkout: IElementsCheckoutActions; analytics: IAnalyticsActions };
85
87
  destroy(): void;
86
88
  }
87
89
 
@@ -158,6 +160,7 @@ interface ILiquidCommerceElementsDevelopmentConfig {
158
160
  customApiUrl?: string;
159
161
  openShadowDom?: boolean;
160
162
  mockMode?: boolean; // when true, sends an 'X-Liquid-Api-Mock-Mode' header to receive mock data
163
+ enableExpressCheckout?: boolean; // show express checkout and the delivery-method switch; off by default, honoured in production
161
164
  }
162
165
  ```
163
166
 
@@ -309,6 +312,7 @@ interface ILiquidCommerceElementsActions {
309
312
  address: IAddressActions;
310
313
  cart: ICartActions;
311
314
  checkout: ICheckoutActions;
315
+ analytics: IAnalyticsActions;
312
316
  }
313
317
  ```
314
318
 
@@ -320,6 +324,74 @@ Checkout actions available in the checkout-only client. This is `ICheckoutAction
320
324
  interface IElementsCheckoutActions extends Omit<ICheckoutActions, 'openCheckout' | 'closeCheckout' | 'toggleCheckout'> {}
321
325
  ```
322
326
 
327
+ ### IAnalyticsActions
328
+
329
+ Reports steps a host renders with its own UI to the SDK's GTM / GA4 stream. On both the full client
330
+ and the checkout-only client. See [Analytics Actions](./actions/analytics-actions.md).
331
+
332
+ ```typescript
333
+ interface IAnalyticsActions {
334
+ search(searchTerm: string): void;
335
+ viewItem(item: IAnalyticsItem): void;
336
+ viewItemList(items: IAnalyticsItem[], list?: IAnalyticsItemList): void;
337
+ selectItem(item: IAnalyticsItem, list?: IAnalyticsItemList): void;
338
+ addToCart(item: IAnalyticsItem): void;
339
+ removeFromCart(item: IAnalyticsItem): void;
340
+ viewCart(items: IAnalyticsItem[]): void;
341
+ beginCheckout(items: IAnalyticsItem[], options?: { coupon?: string }): void;
342
+ addressUpdated(address: IAnalyticsAddress): void;
343
+ addressFailed(failure: IAnalyticsAddressFailure): void;
344
+ productNoAvailability(details: IAnalyticsAvailability): void;
345
+ productSizeNoAvailability(details: IAnalyticsAvailability): void;
346
+ productFulfillmentNoAvailability(details: IAnalyticsFulfillmentAvailability): void;
347
+ }
348
+
349
+ interface IAnalyticsItem {
350
+ id: string; // the selected size's id
351
+ name: string;
352
+ brand?: string;
353
+ size?: string;
354
+ categoryPath?: string; // product catPath
355
+ price?: number; // cents
356
+ quantity?: number;
357
+ type?: string;
358
+ subType?: string;
359
+ image?: string;
360
+ upc?: string;
361
+ groupingId?: string;
362
+ index?: number;
363
+ }
364
+
365
+ interface IAnalyticsItemList {
366
+ id?: string;
367
+ name?: string;
368
+ }
369
+
370
+ interface IAnalyticsAddress {
371
+ placesId?: string;
372
+ formattedAddress?: string;
373
+ address: Partial<IAddressAddress>;
374
+ coordinates?: IAddressCoordinates;
375
+ }
376
+
377
+ interface IAnalyticsAddressFailure {
378
+ placesId?: string;
379
+ formattedAddress?: string;
380
+ address?: Partial<IAddressAddress>;
381
+ error: string;
382
+ }
383
+
384
+ interface IAnalyticsAvailability {
385
+ item: IAnalyticsItem;
386
+ reason: string;
387
+ address?: Partial<IAddressAddress>;
388
+ }
389
+
390
+ interface IAnalyticsFulfillmentAvailability extends IAnalyticsAvailability {
391
+ fulfillmentType: FulfillmentType;
392
+ }
393
+ ```
394
+
323
395
  See [Actions API](./actions/) for detailed method signatures.
324
396
 
325
397
  ---
@@ -373,7 +373,9 @@ window.addEventListener('lce:actions.checkout_item_quantity_decrease', (event) =
373
373
 
374
374
  ### Delivery Method
375
375
 
376
- Fires when the shopper switches a single-item checkout between same-day delivery and shipping.
376
+ Fires when the shopper switches a single-item checkout between same-day delivery and shipping. The
377
+ switch is shown only with `development.enableExpressCheckout: true`, the same opt-in as express
378
+ checkout.
377
379
 
378
380
  ```javascript
379
381
  window.addEventListener('lce:actions.checkout_delivery_method_updated', (event) => {
@@ -427,6 +429,11 @@ window.addEventListener('lce:actions.checkout_express_checkout_availability', (e
427
429
  const { data } = event.detail;
428
430
  console.log(data.available ? `Wallets: ${data.wallets.join(', ')}` : 'No wallets available');
429
431
  });
432
+
433
+ // The shopper tapped a wallet button and its sheet opened
434
+ window.addEventListener('lce:actions.checkout_express_checkout_started', (event) => {
435
+ console.log(`Wallet sheet opened: ${event.detail.data.wallet}`);
436
+ });
430
437
  ```
431
438
 
432
439
  ### Promo Codes
@@ -563,7 +570,12 @@ Apple Pay and Google Pay are offered as express checkout buttons at the top of t
563
570
  the gift toggle. Tapping one collects the shopper's contact and billing details from the wallet and
564
571
  places the order without them completing the checkout forms.
565
572
 
566
- Express checkout is offered to every shopper whose platform can show a wallet. Each wallet is
573
+ Express checkout is off by default: pass `development.enableExpressCheckout: true` in the client config to show it. Without it the checkout element renders
574
+ no express block, and the injection methods below render nothing and resolve to `null`.
575
+
576
+ > **Temporary:** this flag exists only while express checkout and the delivery-method switch are being verified. Once they are confirmed, the flag will be removed and both will always be on.
577
+
578
+ Once enabled, express checkout is offered to every shopper whose platform can show a wallet. Each wallet is
567
579
  requested with Stripe's `always` policy, so the button renders wherever the device supports it rather
568
580
  than only where Stripe judges it good for conversion. The block hides itself entirely — heading,
569
581
  buttons and divider — in four cases: the device or browser offers no wallet, the order is a
@@ -709,7 +709,8 @@ window.addEventListener('lce:actions.checkout_item_engraving_updated', (event) =
709
709
  ### `lce:actions.checkout_delivery_method_updated`
710
710
 
711
711
  Fires when the shopper moves a single-item checkout between same-day delivery and shipping. The order
712
- is re-priced, so the totals change with it.
712
+ is re-priced, so the totals change with it. The switch is shown only with
713
+ `development.enableExpressCheckout: true`.
713
714
 
714
715
  **Data includes:** `cartId`, `fulfillmentType`, `previousFulfillmentType`, `fulfillmentId`.
715
716
 
@@ -893,6 +894,26 @@ window.addEventListener('lce:actions.checkout_express_checkout_availability', (e
893
894
  });
894
895
  ```
895
896
 
897
+ ### `lce:actions.checkout_express_checkout_started`
898
+
899
+ Fires when the shopper taps a wallet button and the SDK opens the wallet sheet, inside the checkout
900
+ or on a block placed with `injectExpressCheckout` / `injectExpressCheckoutElement`. It fires for every
901
+ tap, and not for a tap the block refuses (a total that moved, an unmet order minimum, a second tap
902
+ while an order is being placed). The tap happens inside Stripe's frame, so this is the only way a host
903
+ page learns of it — for instance, to report `add_to_cart` for a product-page wallet with
904
+ [`actions.analytics`](../api/actions/analytics-actions.md).
905
+
906
+ **Data includes:** `cartId`, `wallet` (Stripe's name for it: `'apple_pay'`, `'google_pay'`, …).
907
+
908
+ **Example**
909
+
910
+ ```javascript
911
+ window.addEventListener('lce:actions.checkout_express_checkout_started', (event) => {
912
+ const { wallet } = event.detail.data;
913
+ console.log(`Wallet sheet opened: ${wallet}`);
914
+ });
915
+ ```
916
+
896
917
  ### `lce:actions.checkout_payment_form_failed`
897
918
 
898
919
  Fires when the card form cannot load Stripe.js, so the card fields cannot appear. The shopper sees a
@@ -10,6 +10,11 @@ This runs entirely inside the SDK. In most cases you do not need to configure or
10
10
 
11
11
  It coexists with a host site's own GTM — see [Coexisting With Your Own GTM](#coexisting-with-your-own-gtm) below.
12
12
 
13
+ The one case that needs code: if **your own UI** renders a step Elements would otherwise render — a
14
+ product page, an address picker, a cart, or a "Proceed to checkout" in front of the checkout-only
15
+ client — Elements never sees it. Report it with `actions.analytics` — see
16
+ [Reporting Steps Your Own UI Renders](#reporting-steps-your-own-ui-renders).
17
+
13
18
  ## Supported Environments
14
19
 
15
20
  GTM initialization and every event push are enabled in production and staging. When the SDK is running in Builder mode, no container is loaded and no events are sent.
@@ -93,22 +98,23 @@ Every event automatically carries source-tracking fields identifying the tenant
93
98
 
94
99
  ## Events
95
100
 
96
- All events are GA4-shaped and follow the standard ecommerce schema (`items[]`, `value`, `currency` — the SDK uses `USD`, `coupon`, etc.).
101
+ All events are GA4-shaped and follow the standard ecommerce schema (`items[]`, `value`, `currency` — the SDK uses `USD`, `coupon`, etc.). `search` is the exception: it carries only `search_term`.
97
102
 
98
103
  ### Standard GA4 ecommerce events
99
104
 
100
105
  | Event | Fired when |
101
106
  | --- | --- |
102
- | `view_item` | A shopper views a product |
103
- | `view_item_list` | A shopper views a list of products |
104
- | `select_item` | A shopper selects a product from a list |
105
- | `add_to_cart` | A shopper adds an item to the cart |
106
- | `view_cart` | A shopper views the cart |
107
- | `remove_from_cart` | A shopper removes an item from the cart |
108
- | `begin_checkout` | A shopper begins checkout |
109
- | `add_shipping_info` | Shipping info is added during checkout |
107
+ | `view_item` | A shopper views a product, and again on each size they switch to |
108
+ | `view_item_list` | A product list loads products: its first load, a filtered or searched list, each "load more" |
109
+ | `select_item` | A shopper opens a product from a product list card |
110
+ | `add_to_cart` | A shopper adds an item: from the product component or a list card, `actions.cart.addProduct()` / `actions.checkout.addProduct()`, a cart or checkout quantity increase, or a presale added straight to checkout |
111
+ | `view_cart` | The cart drawer opens with items in it — the cart button, `openCart()` / `toggleCart()`, the checkout's back button — or an add that opens it lands |
112
+ | `remove_from_cart` | A shopper lowers an item's quantity or removes it, in the cart or in the checkout |
113
+ | `begin_checkout` | A shopper begins checkout: the cart's Checkout button (also before its redirect to `checkout.pageUrl`), `actions.checkout.addProduct()`, `openCheckout()` / `toggleCheckout()` opening the drawer, a presale added straight to checkout, or the first wallet tap on express buttons placed on their own |
114
+ | `add_shipping_info` | Shipping info is added during checkout: the customer or gift recipient form is saved, or a wallet (Apple Pay / Google Pay) order hands over the wallet's contact details |
110
115
  | `add_payment_info` | Payment info is added during checkout |
111
116
  | `purchase` | A purchase completes |
117
+ | `search` | A search typed into the product list's search box runs |
112
118
 
113
119
  ### Custom events
114
120
 
@@ -126,8 +132,45 @@ All events are GA4-shaped and follow the standard ecommerce schema (`items[]`, `
126
132
  | `product_size_no_availability` | A selected size has no availability |
127
133
  | `product_fulfillment_no_availability` | A selected fulfillment type has no availability |
128
134
 
135
+ ## Reporting Steps Your Own UI Renders
136
+
137
+ Elements reports the steps its components render. A host that renders some steps itself reports
138
+ them through `actions.analytics`, on the full client and on the checkout-only client:
139
+
140
+ | Action | Event |
141
+ | --- | --- |
142
+ | `search(searchTerm)` | `search` |
143
+ | `viewItem(item)` | `view_item` |
144
+ | `viewItemList(items, list?)` | `view_item_list` |
145
+ | `selectItem(item, list?)` | `select_item` |
146
+ | `addToCart(item)` | `add_to_cart` |
147
+ | `removeFromCart(item)` | `remove_from_cart` |
148
+ | `viewCart(items)` | `view_cart` |
149
+ | `beginCheckout(items, { coupon? })` | `begin_checkout` |
150
+ | `addressUpdated(address)` | `address_updated` |
151
+ | `addressFailed(failure)` | `address_failed` |
152
+ | `productNoAvailability(details)` | `product_no_availability` |
153
+ | `productSizeNoAvailability(details)` | `product_size_no_availability` |
154
+ | `productFulfillmentNoAvailability(details)` | `product_fulfillment_no_availability` |
155
+
156
+ They go through the same pipeline as the SDK's own events — same shape, `tenant_*` fields,
157
+ `send_to` targets, environment gating and queueing — so a report built on Elements events covers
158
+ both. There are no actions for `add_shipping_info`, `add_payment_info`, `purchase` or the promo code
159
+ and gift card events: the Elements checkout reports those itself, and a host reporting them too
160
+ would count every order twice. For the same reason, don't report a step an Elements component
161
+ renders — including `begin_checkout`, which Elements reports from the cart's Checkout button,
162
+ `actions.checkout.addProduct()`, `openCheckout()` / `toggleCheckout()`, a presale, and the first
163
+ wallet tap on express buttons placed on their own.
164
+
165
+ Malformed input never throws: the event is skipped and a warning logged, so reporting can't break
166
+ the host's page.
167
+
168
+ Items take prices in cents, as product responses carry them, and send them in dollars. Full
169
+ signatures and examples: [Analytics Actions](../api/actions/analytics-actions.md).
170
+
129
171
  ## Related Docs
130
172
 
131
173
  - [Events Guide](../guides/events.md)
174
+ - [Analytics Actions](../api/actions/analytics-actions.md)
132
175
  - [Client API](../api/client.md)
133
176
  - [Troubleshooting](./troubleshooting.md)
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "LiquidCommerce Elements SDK",
4
4
  "license": "UNLICENSED",
5
5
  "author": "LiquidCommerce Team",
6
- "version": "2.6.0-beta.127",
6
+ "version": "2.6.0-beta.129",
7
7
  "homepage": "https://docs.liquidcommerce.co/elements-sdk",
8
8
  "repository": {
9
9
  "type": "git",