@liquidcommerce/elements-sdk 2.7.0 → 2.7.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.
Files changed (81) hide show
  1. package/README.md +83 -2750
  2. package/dist/index.checkout.esm.js +6898 -6837
  3. package/dist/index.esm.js +11463 -10993
  4. package/dist/types/auto-initialize/shared-utils.d.ts +5 -0
  5. package/dist/types/constants/core.constant.d.ts +0 -4
  6. package/dist/types/core/base-component.service.d.ts +2 -1
  7. package/dist/types/core/pubsub/interfaces/checkout.interface.d.ts +1 -0
  8. package/dist/types/enums/core.enum.d.ts +11 -0
  9. package/dist/types/interfaces/configs/product-list.interface.d.ts +2 -2
  10. package/dist/types/interfaces/core.interface.d.ts +5 -4
  11. package/dist/types/modules/address/address-input.component.d.ts +11 -0
  12. package/dist/types/modules/checkout/components/checkout-stripe-form.component.d.ts +2 -1
  13. package/dist/types/modules/product-list/components/card-components/index.d.ts +3 -0
  14. package/dist/types/modules/product-list/components/card-components/product-badge.d.ts +8 -0
  15. package/dist/types/modules/product-list/components/card-components/product-fulfillments.d.ts +2 -0
  16. package/dist/types/modules/product-list/components/card-components/product-price-and-personalization.d.ts +13 -0
  17. package/dist/types/modules/product-list/components/card-components/product-title.d.ts +6 -0
  18. package/dist/types/modules/product-list/components/index.d.ts +1 -0
  19. package/dist/types/modules/product-list/components/product-list-engraving.component.d.ts +5 -1
  20. package/dist/types/modules/product-list/components/product-list-product-pre-cart.component.d.ts +28 -0
  21. package/dist/types/modules/product-list/components/product-list-retailers.component.d.ts +10 -2
  22. package/dist/types/modules/product-list/product-list-card.component.d.ts +0 -5
  23. package/dist/types/modules/product-list/product-list.commands.d.ts +11 -2
  24. package/dist/types/modules/product-list/product-list.interface.d.ts +1 -0
  25. package/dist/types/modules/ui-components/engraving/engraving-form.component.d.ts +11 -2
  26. package/dist/types/modules/ui-components/lce-element/lce-element.component.d.ts +2 -1
  27. package/dist/types/utils/dom-compat.d.ts +2 -0
  28. package/docs/gitbook/actions.md +964 -0
  29. package/docs/gitbook/address.md +48 -0
  30. package/docs/gitbook/cart.md +65 -0
  31. package/docs/gitbook/checkout.md +131 -0
  32. package/docs/gitbook/events.md +1765 -0
  33. package/docs/gitbook/overview.md +166 -0
  34. package/docs/gitbook/product.md +64 -0
  35. package/docs/gitbook/quick-start-guide.md +393 -0
  36. package/docs/v1/README.md +210 -0
  37. package/docs/v1/api/actions/address-actions.md +281 -0
  38. package/docs/v1/api/actions/cart-actions.md +337 -0
  39. package/docs/v1/api/actions/checkout-actions.md +387 -0
  40. package/docs/v1/api/actions/product-actions.md +115 -0
  41. package/docs/v1/api/client.md +482 -0
  42. package/docs/v1/api/configuration.md +1 -0
  43. package/docs/v1/api/injection-methods.md +247 -0
  44. package/docs/v1/api/typescript-types.md +1 -0
  45. package/docs/v1/api/ui-helpers.md +200 -0
  46. package/docs/v1/examples/advanced-patterns.md +96 -0
  47. package/docs/v1/examples/checkout-flow.md +91 -0
  48. package/docs/v1/examples/custom-theming.md +63 -0
  49. package/docs/v1/examples/multi-product-page.md +90 -0
  50. package/docs/v1/examples/simple-product-page.md +89 -0
  51. package/docs/v1/getting-started/concepts.md +507 -0
  52. package/docs/v1/getting-started/installation.md +328 -0
  53. package/docs/v1/getting-started/quick-start.md +405 -0
  54. package/docs/v1/guides/address-component.md +431 -0
  55. package/docs/v1/guides/best-practices.md +324 -0
  56. package/docs/v1/guides/cart-component.md +737 -0
  57. package/docs/v1/guides/checkout-component.md +672 -0
  58. package/docs/v1/guides/events.md +926 -0
  59. package/docs/v1/guides/product-component.md +686 -0
  60. package/docs/v1/guides/product-list-component.md +598 -0
  61. package/docs/v1/guides/theming.md +216 -0
  62. package/docs/v1/integration/angular.md +39 -0
  63. package/docs/v1/integration/laravel.md +41 -0
  64. package/docs/v1/integration/nextjs.md +60 -0
  65. package/docs/v1/integration/proxy-setup.md +89 -0
  66. package/docs/v1/integration/react.md +64 -0
  67. package/docs/v1/integration/vanilla-js.md +84 -0
  68. package/docs/v1/integration/vue.md +34 -0
  69. package/docs/v1/reference/browser-support.md +44 -0
  70. package/docs/v1/reference/error-handling.md +70 -0
  71. package/docs/v1/reference/performance.md +54 -0
  72. package/docs/v1/reference/troubleshooting.md +64 -0
  73. package/package.json +1 -1
  74. package/docs/ACTIONS.md +0 -1301
  75. package/docs/BROWSER_SUPPORT.md +0 -279
  76. package/docs/CONFIGURATION.md +0 -997
  77. package/docs/DOCUMENTATION_INDEX.md +0 -319
  78. package/docs/EVENTS.md +0 -798
  79. package/docs/PROXY.md +0 -228
  80. package/docs/THEMING.md +0 -681
  81. package/docs/TROUBLESHOOTING.md +0 -793
package/docs/EVENTS.md DELETED
@@ -1,798 +0,0 @@
1
- # Elements SDK Events - Partner Implementation Guide
2
-
3
- > **Browser Support**: This SDK supports 2018+ browsers (Chrome 66+, Firefox 60+, Safari 12+) with comprehensive polyfills. See `docs/BROWSER_SUPPORT.md` for details.
4
-
5
- ## What Are Events and Why Use Them?
6
-
7
- Events are real-time notifications that tell you exactly what your customers are doing on your site. Think of them as your digital sales assistant that whispers in your ear every time a customer looks at a product, adds something to cart, or starts checkout.
8
-
9
- **Business Benefits:**
10
- - **Track Revenue Impact**: See which products drive the most sales
11
- - **Optimize Conversion**: Identify where customers drop off
12
- - **Personalize Experience**: Trigger custom actions based on customer behavior
13
- - **Measure Performance**: Get real metrics on your e-commerce funnel
14
- - **Automate Marketing**: Send targeted emails/SMS based on customer actions
15
-
16
- ## How It Works
17
-
18
- When customers interact with your LiquidCommerce elements, events automatically fire. You simply "listen" for these events and take action:
19
-
20
- ```javascript
21
- // Example: When someone adds to cart, send them a discount code
22
- window.addEventListener('lce:actions.product_add_to_cart', function(event) {
23
- // Customer just added a product to cart!
24
- const data = event.detail.data;
25
-
26
- // Maybe send them a discount popup
27
- showDiscountPopup(data.identifier);
28
-
29
- // Or track in your analytics
30
- analytics.track('Product Added', {
31
- identifier: data.identifier,
32
- quantity: data.quantity,
33
- upc: data.upc
34
- });
35
- });
36
- ```
37
-
38
- ## Quick Implementation Guide
39
-
40
- ### Step 1: Choose Your Goal
41
- What do you want to achieve? Pick one:
42
-
43
- **🎯 Track Sales Performance**
44
- ```javascript
45
- // Track when products are viewed and added to cart
46
- window.addEventListener('lce:actions.product_loaded', function(event) {
47
- // Product was viewed - track in your analytics
48
- const product = event.detail.data;
49
- console.log('Customer viewed:', product.name);
50
- });
51
-
52
- window.addEventListener('lce:actions.product_add_to_cart', function(event) {
53
- // Product was added to cart - this is a conversion!
54
- const data = event.detail.data;
55
- console.log('SALE OPPORTUNITY:', data.identifier, 'qty:', data.quantity);
56
- });
57
- ```
58
-
59
- **🛒 Recover Abandoned Carts**
60
- ```javascript
61
- // Detect when someone opens cart but doesn't buy
62
- window.addEventListener('lce:actions.cart_opened', function(event) {
63
- // Start a timer - if they don't complete purchase in 10 minutes, send email
64
- setTimeout(function() {
65
- sendAbandonedCartEmail();
66
- }, 10 * 60 * 1000); // 10 minutes
67
- });
68
-
69
- window.addEventListener('lce:actions.checkout_submit_completed', function(event) {
70
- // They bought! Cancel the abandoned cart email
71
- cancelAbandonedCartEmail();
72
- });
73
- ```
74
-
75
- **💰 Maximize Revenue**
76
- ```javascript
77
- // Offer upsells when they add expensive items
78
- window.addEventListener('lce:actions.product_add_to_cart', function(event) {
79
- const data = event.detail.data;
80
-
81
- // Trigger upsell based on product identifier
82
- showUpsellPopup(data.identifier);
83
- });
84
- ```
85
-
86
- ## Step 2: Complete Event List & What They Mean
87
-
88
- ### 🚀 SDK Lifecycle Events
89
- ```javascript
90
- // When SDK is ready to use
91
- 'lce:actions.client_ready' // → "SDK is initialized and ready to use"
92
- ```
93
-
94
- **Example Usage:**
95
- ```javascript
96
- window.addEventListener('lce:actions.client_ready', function(event) {
97
- const { isReady, message, timestamp, version } = event.detail.data;
98
- console.log('SDK Ready:', version);
99
- // Now safe to call SDK methods
100
- });
101
- ```
102
-
103
- ### 🛍️ Product Events (Track Customer Interest)
104
- ```javascript
105
- // When a customer views a product
106
- 'lce:actions.product_loaded' // → "Customer is interested in this product"
107
-
108
- // When they add to cart
109
- 'lce:actions.product_add_to_cart' // → "Hot lead! Customer wants to buy"
110
-
111
- // When they change quantity
112
- 'lce:actions.product_quantity_increase' // → "Customer wants more"
113
- 'lce:actions.product_quantity_decrease' // → "Customer wants less"
114
-
115
- // When they change options
116
- 'lce:actions.product_size_changed' // → "Customer has size preferences"
117
- 'lce:actions.product_fulfillment_type_changed' // → "Delivery preference changed"
118
- 'lce:actions.product_fulfillment_changed' // → "Customer selected specific retailer/fulfillment"
119
- ```
120
-
121
- **Note on Personalization:** Product personalization (engraving) is added during the add-to-cart action. The personalization is included in the `product_add_to_cart` event data. Once in cart, use `cart_item_engraving_updated` to track changes.
122
-
123
- #### Product Details Event Data
124
- When `lce:actions.product_loaded` fires, you get comprehensive product information:
125
-
126
- ```javascript
127
- window.addEventListener('lce:actions.product_loaded', function(event) {
128
- const product = event.detail.data;
129
-
130
- // Basic Information
131
- console.log(product.id); // Product ID
132
- console.log(product.name); // Product name
133
- console.log(product.brand); // Brand name
134
- console.log(product.category); // Category
135
- console.log(product.catPath); // Category path
136
- console.log(product.classification); // Product classification
137
- console.log(product.type); // Product type
138
- console.log(product.subType); // Product sub-type
139
- console.log(product.salsifyGrouping); // Salsify grouping ID
140
-
141
- // Visual Assets
142
- console.log(product.mainImage); // Main product image URL
143
- console.log(product.images); // Array of all product images
144
-
145
- // Product Attributes
146
- console.log(product.region); // Region (e.g., "Napa Valley")
147
- console.log(product.country); // Country of origin
148
- console.log(product.material); // Material type
149
- console.log(product.abv); // Alcohol by volume
150
- console.log(product.proof); // Proof
151
- console.log(product.age); // Age statement
152
- console.log(product.color); // Color description
153
- console.log(product.flavor); // Flavor profile
154
- console.log(product.variety); // Variety (e.g., "Cabernet Sauvignon")
155
- console.log(product.appellation); // Appellation
156
- console.log(product.vintage); // Vintage year
157
-
158
- // Descriptions
159
- console.log(product.description); // Plain text description
160
- console.log(product.htmlDescription); // HTML formatted description
161
- console.log(product.tastingNotes); // Tasting notes
162
-
163
- // Pricing
164
- console.log(product.priceInfo); // { min, max, avg } pricing across fulfillments
165
-
166
- // Available Sizes & Fulfillments
167
- console.log(product.sizes); // All available sizes with fulfillment options
168
- console.log(product.selectedSizeId); // Currently selected size
169
- console.log(product.selectedFulfillmentId); // Currently selected fulfillment
170
- console.log(product.selectedFulfillmentType); // 'shipping' or 'onDemand'
171
- });
172
- ```
173
-
174
- **Use Cases:**
175
- - **Rich Analytics**: Track which product attributes drive conversions
176
- - **Personalized Recommendations**: Suggest similar products based on variety, region, or flavor
177
- - **Content Display**: Show detailed product information on your custom UI
178
- - **Search & Filtering**: Build custom search based on product attributes
179
-
180
- ### 🛒 Cart Events (Track Purchase Intent)
181
- ```javascript
182
- // Cart lifecycle
183
- 'lce:actions.cart_loaded' // → "Cart data has been loaded and is ready"
184
- 'lce:actions.cart_opened' // → "Customer is reviewing their purchase"
185
- 'lce:actions.cart_closed' // → "Customer might be comparison shopping"
186
-
187
- // Cart changes
188
- 'lce:actions.cart_updated' // → "Customer modified their order"
189
- 'lce:actions.cart_reset' // → "Customer cleared everything - intervention needed!"
190
- 'lce:actions.cart_failed' // → "Cart operation failed"
191
-
192
- // Item management
193
- 'lce:actions.cart_item_added' // → "Customer committed to another product"
194
- 'lce:actions.cart_item_removed' // → "Customer changed their mind"
195
- 'lce:actions.cart_item_quantity_increase' // → "Customer added more of an item"
196
- 'lce:actions.cart_item_quantity_decrease' // → "Customer reduced item quantity"
197
- 'lce:actions.cart_item_engraving_updated' // → "Customer updated/removed item personalization"
198
- ```
199
-
200
- **Personalization Events:**
201
- ```javascript
202
- // Track when customers add or modify personalization
203
- window.addEventListener('lce:actions.cart_item_engraving_updated', function(event) {
204
- const { identifier, engravingLines, hasEngraving } = event.detail.data;
205
-
206
- if (hasEngraving && engravingLines.length > 0) {
207
- console.log(`Personalization added/updated: ${engravingLines.join(', ')}`);
208
- } else {
209
- console.log('Personalization removed from item');
210
- }
211
- });
212
- ```
213
-
214
- #### Cart Details Event Data
215
- When `lce:actions.cart_loaded` or `lce:actions.cart_updated` fires, you get complete cart information:
216
-
217
- ```javascript
218
- window.addEventListener('lce:actions.cart_loaded', function(event) {
219
- const cart = event.detail.data;
220
-
221
- // Cart Identification
222
- console.log(cart.id); // Cart ID
223
- console.log(cart.promoCode); // Applied promo code (if any)
224
-
225
- // Cart Items
226
- console.log(cart.items); // Object with all cart items
227
- console.log(cart.itemCount); // Total number of items in cart
228
-
229
- // Each item contains:
230
- Object.values(cart.items).forEach(item => {
231
- console.log(item.id); // Cart item ID
232
- console.log(item.name); // Product name
233
- console.log(item.brand); // Brand
234
- console.log(item.salsifyGrouping); // Salsify grouping ID
235
- console.log(item.catPath); // Category path
236
- console.log(item.size); // Size description
237
- console.log(item.volume); // Volume
238
- console.log(item.uom); // Unit of measure
239
- console.log(item.pack); // Is pack (boolean)
240
- console.log(item.packDesc); // Pack description
241
- console.log(item.container); // Container type
242
- console.log(item.containerType); // Container type classification
243
- console.log(item.price); // Total price (unitPrice × quantity)
244
- console.log(item.unitPrice); // Price per unit
245
- console.log(item.quantity); // Quantity
246
- console.log(item.maxQuantity); // Maximum allowed quantity
247
- console.log(item.mainImage); // Product image URL
248
- console.log(item.upc); // UPC code
249
- console.log(item.sku); // SKU
250
- console.log(item.partNumber); // Part number
251
- console.log(item.retailerId); // Retailer ID
252
- console.log(item.fulfillmentId); // Fulfillment ID
253
- console.log(item.attributes); // Item attributes (engraving, etc.)
254
- });
255
-
256
- // Location Information
257
- console.log(cart.location.placesId); // Google Places ID
258
- console.log(cart.location.address); // Address object
259
- console.log(cart.location.coordinates); // Lat/long coordinates
260
-
261
- // Financial Breakdown
262
- console.log(cart.amounts.subtotal); // Subtotal
263
- console.log(cart.amounts.deliveryFee); // Delivery fee
264
- console.log(cart.amounts.shippingFee); // Shipping fee
265
- console.log(cart.amounts.platformFee); // Platform fee
266
- console.log(cart.amounts.engravingFee); // Engraving/personalization fee
267
- console.log(cart.amounts.discounts); // Total discounts
268
- console.log(cart.amounts.giftCardTotal); // Gift card total applied
269
- console.log(cart.amounts.total); // Final total
270
-
271
- // Timestamps
272
- console.log(cart.createdAt); // When cart was created
273
- console.log(cart.updatedAt); // Last update timestamp
274
- });
275
- ```
276
-
277
- **Use Cases:**
278
- - **Abandoned Cart Recovery**: Track cart value and items for targeted recovery campaigns
279
- - **Revenue Analytics**: Monitor average cart value, most popular items, cart composition
280
- - **Inventory Management**: Track which products are frequently added/removed
281
- - **Pricing Analysis**: Analyze impact of fees, discounts, and gift cards on cart totals
282
-
283
- ### 💳 Checkout Events (Track Purchase Process)
284
- ```javascript
285
- // Checkout lifecycle
286
- 'lce:actions.checkout_loaded' // → "Checkout data has been loaded and is ready"
287
- 'lce:actions.checkout_opened' // → "Customer is ready to buy!"
288
- 'lce:actions.checkout_closed' // → "Customer left checkout"
289
- 'lce:actions.checkout_failed' // → "Checkout operation failed"
290
-
291
- // Checkout submission
292
- 'lce:actions.checkout_submit_started' // → "Payment processing..."
293
- 'lce:actions.checkout_submit_completed' // → "SALE COMPLETED! 🎉"
294
- 'lce:actions.checkout_submit_failed' // → "Sale lost - fix the issue!"
295
-
296
- // Form updates (Security: returns boolean only, no sensitive data)
297
- 'lce:actions.checkout_customer_information_updated' // → "Customer filling out details"
298
- // Data: boolean (true) - No customer data exposed for security
299
- 'lce:actions.checkout_billing_information_updated' // → "Payment info being entered"
300
- // Data: boolean (true) - No billing data exposed for security
301
- 'lce:actions.checkout_gift_information_updated' // → "Gift recipient info updated"
302
- // Data: boolean (true) - No recipient data exposed for security
303
-
304
- // Checkout options
305
- 'lce:actions.checkout_is_gift_toggled' // → "Customer toggled gift option"
306
- 'lce:actions.checkout_billing_same_as_shipping_toggled' // → "Customer toggled billing address option"
307
- 'lce:actions.checkout_marketing_preferences_toggled' // → "Customer updated marketing preferences"
308
-
309
- // Item management in checkout
310
- 'lce:actions.checkout_item_removed' // → "Customer removed item from checkout"
311
- 'lce:actions.checkout_item_quantity_increase' // → "Customer increased item quantity in checkout"
312
- 'lce:actions.checkout_item_quantity_decrease' // → "Customer decreased item quantity in checkout"
313
- 'lce:actions.checkout_item_engraving_updated' // → "Customer removed personalization in checkout"
314
-
315
- // Tips (for on-demand delivery)
316
- 'lce:actions.checkout_tip_updated' // → "Customer updated delivery tip"
317
- ```
318
-
319
- **🔒 Security Note on Form Update Events:**
320
- The following events return only a boolean `true` value instead of customer data for security reasons:
321
- - `checkout_customer_information_updated` - No customer contact details exposed
322
- - `checkout_billing_information_updated` - No payment or billing address details exposed
323
- - `checkout_gift_information_updated` - No gift recipient details exposed
324
-
325
- This design prevents malicious scripts from intercepting sensitive customer information (names, emails, phone numbers, addresses, etc.) while still allowing you to track form completion for analytics. **This is intentional and prioritizes customer privacy and security.**
326
-
327
- ```javascript
328
- // ✅ Correct: Track form completion securely
329
- window.addEventListener('lce:actions.checkout_customer_information_updated', function(event) {
330
- const completed = event.detail.data; // boolean: true
331
-
332
- // Track the milestone without exposing customer data
333
- analytics.track('Checkout Step Completed', { step: 'customer_info' });
334
- updateProgressBar('customer_info');
335
- });
336
-
337
- window.addEventListener('lce:actions.checkout_billing_information_updated', function(event) {
338
- const completed = event.detail.data; // boolean: true
339
-
340
- // Track billing form completion
341
- analytics.track('Checkout Step Completed', { step: 'billing_info' });
342
- updateProgressBar('billing_info');
343
- });
344
-
345
- // 🚫 You will NOT receive customer data like names, emails, addresses, etc.
346
- // This protects your customers from malicious scripts and data breaches.
347
- ```
348
-
349
- **Important Note on Checkout Personalization:**
350
- Personalization cannot be edited during checkout - only removed. This is by design to prevent order processing complications. If a customer wants to modify personalization, they must return to the cart. The checkout only displays personalization details and provides a remove option.
351
-
352
- #### Checkout Details Event Data
353
- When you call `actions.checkout.getDetails()`, you get comprehensive checkout information:
354
-
355
- **Note:** The `lce:actions.checkout_loaded` event only contains `{ cartId: string }`. To get full checkout details, use `actions.checkout.getDetails()`.
356
-
357
- ```javascript
358
- // Get full checkout details via action
359
- const checkout = actions.checkout.getDetails();
360
-
361
- // Checkout Identification
362
- console.log(checkout.cartId); // Associated cart ID
363
-
364
- // Checkout Status Flags
365
- console.log(checkout.acceptedAccountCreation); // Customer accepted account creation
366
- console.log(checkout.hasAgeVerify); // Age verification required
367
- console.log(checkout.hasSubstitutionPolicy); // Substitution policy accepted
368
- console.log(checkout.isGift); // Order is a gift
369
- console.log(checkout.billingSameAsShipping); // Billing address same as shipping
370
- console.log(checkout.hasPromoCode); // Promo code applied
371
- console.log(checkout.hasGiftCards); // Gift cards applied
372
-
373
- // Marketing Preferences
374
- console.log(checkout.marketingPreferences.canEmail); // Email opt-in status
375
- console.log(checkout.marketingPreferences.canSms); // SMS opt-in status
376
-
377
- // Order Summary
378
- console.log(checkout.itemCount); // Total items in checkout
379
-
380
- // Financial Breakdown
381
- console.log(checkout.amounts.subtotal); // Subtotal
382
- console.log(checkout.amounts.deliveryFee); // Delivery fee
383
- console.log(checkout.amounts.shippingFee); // Shipping fee
384
- console.log(checkout.amounts.platformFee); // Platform fee
385
- console.log(checkout.amounts.engravingFee); // Engraving/personalization fee
386
- console.log(checkout.amounts.discounts); // Total discounts
387
- console.log(checkout.amounts.giftCardTotal); // Gift card total applied
388
- console.log(checkout.amounts.tax); // Tax amount
389
- console.log(checkout.amounts.bottleDeposits); // Bottle deposit fees
390
- console.log(checkout.amounts.total); // Final total
391
-
392
- // Checkout Items (detailed product information)
393
- console.log(checkout.items); // Object with all checkout items
394
-
395
- // Each checkout item contains comprehensive details:
396
- Object.values(checkout.items).forEach(item => {
397
- console.log(item.cartItemId); // Cart item ID
398
- console.log(item.liquidId); // Liquid ID
399
- console.log(item.variantId); // Variant ID
400
- console.log(item.name); // Product name
401
- console.log(item.brand); // Brand
402
- console.log(item.salsifyGrouping); // Salsify grouping ID
403
- console.log(item.catPath); // Category path
404
-
405
- // Size & Container Information
406
- console.log(item.size); // Size description
407
- console.log(item.volume); // Volume
408
- console.log(item.uom); // Unit of measure
409
- console.log(item.pack); // Is pack (boolean)
410
- console.log(item.packDesc); // Pack description
411
- console.log(item.container); // Container type
412
- console.log(item.containerType); // Container type classification
413
-
414
- // Product Attributes
415
- console.log(item.proof); // Proof
416
- console.log(item.abv); // Alcohol by volume
417
-
418
- // Pricing
419
- console.log(item.price); // Total price (unitPrice × quantity)
420
- console.log(item.unitPrice); // Price per unit
421
- console.log(item.unitTax); // Tax per unit
422
- console.log(item.bottleDeposits); // Bottle deposit fees
423
- console.log(item.quantity); // Quantity
424
-
425
- // Identifiers
426
- console.log(item.upc); // UPC code
427
- console.log(item.sku); // SKU
428
- console.log(item.partNumber); // Part number
429
-
430
- // Fulfillment Information
431
- console.log(item.retailerId); // Retailer ID
432
- console.log(item.retailerName); // Retailer name
433
- console.log(item.fulfillmentId); // Fulfillment ID
434
- console.log(item.expectationDetail); // Delivery expectation details
435
-
436
- // Visual Assets
437
- console.log(item.mainImage); // Product image URL
438
-
439
- // Item Attributes (engraving, etc.)
440
- console.log(item.attributes); // Item attributes object
441
- });
442
- ```
443
-
444
- **Use Cases:**
445
- - **Order Analytics**: Track checkout completion rates, average order values, popular items
446
- - **Marketing Optimization**: Analyze opt-in rates, gift order patterns, promo code effectiveness
447
- - **Revenue Tracking**: Monitor tax collection, fees, discounts, and gift card usage
448
- - **Customer Insights**: Understand purchasing patterns, preferred retailers, delivery preferences
449
- - **Compliance**: Track age verification requirements, substitution policy acceptance
450
-
451
- ### 📍 Address Events (Track Shipping Preferences)
452
- ```javascript
453
- 'lce:actions.address_updated' // → "Customer entered shipping address"
454
- 'lce:actions.address_cleared' // → "Customer removed address"
455
- 'lce:actions.address_failed' // → "Address validation failed"
456
- ```
457
-
458
- ### 🔔 **NEW: Action Feedback Events** (Track Action Success/Failure)
459
-
460
- These events fire when programmatic actions succeed or fail, giving you complete control over user feedback:
461
-
462
- #### 🛒 **Cart Action Feedback**
463
- ```javascript
464
- // Product addition feedback
465
- 'lce:actions.cart_product_add_success' // → "Products successfully added to cart"
466
- // Data: { itemsAdded: number, identifiers: string[] }
467
-
468
- 'lce:actions.cart_product_add_failed' // → "Products could not be added to cart"
469
- // Data: { identifiers: string[], error: string }
470
-
471
- // Promo code feedback
472
- 'lce:actions.cart_promo_code_applied' // → "Promo code worked - show success!"
473
- // Data: { discount?: number, newTotal?: number }
474
-
475
- 'lce:actions.cart_promo_code_removed' // → "Promo code removed successfully"
476
- // Data: { newTotal?: number }
477
-
478
- 'lce:actions.cart_promo_code_failed' // → "Promo code didn't work - show error"
479
- // Data: { error: string }
480
- ```
481
-
482
- #### 💳 **Checkout Action Feedback**
483
- ```javascript
484
- // Product addition feedback
485
- 'lce:actions.checkout_product_add_success' // → "Products added to checkout successfully"
486
- // Data: { itemsAdded: number, identifiers: string[], isPresale?: boolean }
487
-
488
- 'lce:actions.checkout_product_add_failed' // → "Could not add products to checkout"
489
- // Data: { identifiers: string[], error: string, isPresale?: boolean }
490
-
491
- // Promo code feedback
492
- 'lce:actions.checkout_promo_code_applied' // → "Checkout discount applied!"
493
- // Data: { discount?: number, newTotal?: number }
494
-
495
- 'lce:actions.checkout_promo_code_removed' // → "Checkout discount removed"
496
- // Data: { newTotal?: number }
497
-
498
- 'lce:actions.checkout_promo_code_failed' // → "Checkout discount failed"
499
- // Data: { error: string }
500
-
501
- // Gift card feedback
502
- 'lce:actions.checkout_gift_card_applied' // → "Gift card applied successfully!"
503
- // Data: { newTotal?: number }
504
-
505
- 'lce:actions.checkout_gift_card_removed' // → "Gift card removed"
506
- // Data: { newTotal?: number }
507
-
508
- 'lce:actions.checkout_gift_card_failed' // → "Gift card could not be applied"
509
- // Data: { error: string }
510
- ```
511
-
512
- #### 🔒 **Security Note**
513
- Action feedback events **never expose sensitive information** like promo codes or gift card codes. This prevents malicious scripts from stealing sensitive data while still providing rich feedback for legitimate developers.
514
-
515
- **Example: Secure Action Feedback**
516
- ```javascript
517
- // Fire the action (simple)
518
- await actions.cart.applyPromoCode('SECRET20');
519
-
520
- // Get feedback (secure)
521
- window.addEventListener('lce:actions.cart_promo_code_applied', function(event) {
522
- const { discount, newTotal } = event.detail.data;
523
- // ✅ You get: discount amount, new total
524
- // 🚫 You DON'T get: 'SECRET20' (secure!)
525
-
526
- showSuccessMessage(`🎉 Discount applied! You saved $${discount}!`);
527
- updateCartTotal(newTotal);
528
- });
529
- ```
530
-
531
- ## Step 3: Real-World Implementation Examples
532
-
533
- ### 🔔 **NEW Example: Smart Action Feedback with Perfect UX**
534
- ```javascript
535
- // Perfect promo code experience with action feedback
536
- async function applyPromoCodeWithFeedback(code) {
537
- // Show loading state
538
- showLoadingMessage('Applying promo code...');
539
-
540
- // Set up event listeners BEFORE firing action
541
- const successHandler = (event) => {
542
- const { discount, newTotal } = event.detail.data;
543
- hideLoadingMessage();
544
- showSuccessMessage(`🎉 Success! You saved $${discount}!`);
545
- updatePriceDisplay(newTotal);
546
-
547
- // Track successful promo usage
548
- analytics.track('Promo Applied', {
549
- discount: discount,
550
- newTotal: newTotal
551
- });
552
-
553
- // Clean up
554
- cleanup();
555
- };
556
-
557
- const failureHandler = (event) => {
558
- const { error } = event.detail.data;
559
- hideLoadingMessage();
560
- showErrorMessage('Promo code could not be applied. Please try again.');
561
-
562
- // Track failed attempts (for optimization)
563
- analytics.track('Promo Failed', { error: error });
564
-
565
- // Maybe suggest alternatives
566
- suggestAlternativePromos();
567
-
568
- // Clean up
569
- cleanup();
570
- };
571
-
572
- const cleanup = () => {
573
- window.removeEventListener('lce:actions.cart_promo_code_applied', successHandler);
574
- window.removeEventListener('lce:actions.cart_promo_code_failed', failureHandler);
575
- };
576
-
577
- // Attach listeners
578
- window.addEventListener('lce:actions.cart_promo_code_applied', successHandler);
579
- window.addEventListener('lce:actions.cart_promo_code_failed', failureHandler);
580
-
581
- // Fire the action
582
- await actions.cart.applyPromoCode(code);
583
- }
584
-
585
- // Usage: Perfect UX every time!
586
- applyPromoCodeWithFeedback('SAVE20');
587
- ```
588
-
589
- ### 🎯 Example 1: Boost Your Sales with Smart Promotions
590
- ```javascript
591
- // Automatically offer discounts for high-value carts
592
- window.addEventListener('lce:actions.cart_updated', function(event) {
593
- const cart = event.detail.data.current;
594
-
595
- if (cart.amounts.total > 200 && !cart.promoCode) {
596
- // Show them a 10% off popup
597
- showPopup("Get 10% off orders over $200! Use code: SAVE10");
598
- }
599
- });
600
-
601
- // Track which products make people abandon checkout
602
- window.addEventListener('lce:actions.checkout_opened', function(event) {
603
- window.checkoutStartTime = new Date();
604
- });
605
-
606
- window.addEventListener('lce:actions.checkout_closed', function(event) {
607
- // If they close checkout without buying, they abandoned
608
- if (window.checkoutStartTime) {
609
- const timeSpent = new Date() - window.checkoutStartTime;
610
- console.log('Checkout abandoned after', timeSpent/1000, 'seconds');
611
- // Send this data to your analytics to find problem products
612
- }
613
- });
614
- ```
615
-
616
- ### 📧 Example 2: Automated Email Marketing
617
- ```javascript
618
- // Build an email list from cart abandoners
619
- window.addEventListener('lce:actions.cart_opened', function(event) {
620
- // Customer opened cart - start tracking
621
- window.cartOpenTime = new Date();
622
- window.cartItems = event.detail.data.items;
623
- });
624
-
625
- window.addEventListener('lce:actions.checkout_submit_completed', function(event) {
626
- // They bought! No need for abandonment email
627
- window.cartOpenTime = null;
628
- });
629
-
630
- // Check every 5 minutes if cart was abandoned
631
- setInterval(function() {
632
- if (window.cartOpenTime) {
633
- const timeSinceOpen = new Date() - window.cartOpenTime;
634
- if (timeSinceOpen > 15 * 60 * 1000) { // 15 minutes
635
- // Send abandonment email with cart items
636
- sendAbandonmentEmail(window.cartItems);
637
- window.cartOpenTime = null; // Don't send again
638
- }
639
- }
640
- }, 5 * 60 * 1000);
641
- ```
642
-
643
- ### 📊 Example 3: Track Your Best-Performing Products
644
- ```javascript
645
- // Keep a running tally of product performance
646
- let productStats = {};
647
-
648
- window.addEventListener('lce:actions.product_loaded', function(event) {
649
- const product = event.detail.data;
650
-
651
- // Initialize stats if first time seeing this product
652
- if (!productStats[product.id]) {
653
- productStats[product.id] = {
654
- name: product.name,
655
- views: 0,
656
- addedToCarts: 0,
657
- conversions: 0
658
- };
659
- }
660
-
661
- productStats[product.id].views++;
662
- });
663
-
664
- window.addEventListener('lce:actions.product_add_to_cart', function(event) {
665
- const data = event.detail.data;
666
- // Note: product_add_to_cart only has identifier, not full product details
667
- if (productStats[data.identifier]) {
668
- productStats[data.identifier].addedToCarts++;
669
- }
670
- });
671
-
672
- window.addEventListener('lce:actions.checkout_submit_completed', function(event) {
673
- const order = event.detail.data;
674
- console.log('Order completed:', order.orderNumber, 'Total:', order.orderTotal);
675
-
676
- // Send stats to your analytics dashboard
677
- console.log('Product Performance:', productStats);
678
-
679
- // Track conversion in analytics
680
- analytics.track('Purchase', {
681
- orderNumber: order.orderNumber,
682
- total: order.orderTotal
683
- });
684
- });
685
- ```
686
-
687
- ### 🔥 Example 4: Create Urgency with Live Updates
688
- ```javascript
689
- // Show live activity to create FOMO (Fear of Missing Out)
690
- window.addEventListener('lce:actions.product_add_to_cart', function(event) {
691
- const data = event.detail.data;
692
-
693
- // Show notification to other visitors
694
- showNotification(`Someone just bought product ${data.identifier}! Only 3 left!`);
695
-
696
- // Update inventory count on the page
697
- updateInventoryDisplay(data.identifier, -1);
698
- });
699
-
700
- window.addEventListener('lce:actions.cart_opened', function(event) {
701
- // Show how many people are currently viewing this product
702
- showViewerCount("👀 5 people are looking at this right now");
703
- });
704
- ```
705
-
706
- ## Common Use Cases & How to Implement
707
-
708
- ### 🛒 **Cart Abandonment Recovery**
709
- **The Problem**: 70% of carts are abandoned
710
- **The Solution**: Automatic follow-up based on events
711
-
712
- ```javascript
713
- // Set up cart abandonment tracking
714
- let abandonmentTimer;
715
-
716
- window.addEventListener('lce:actions.cart_opened', function() {
717
- // Reset timer each time they open cart
718
- clearTimeout(abandonmentTimer);
719
-
720
- abandonmentTimer = setTimeout(function() {
721
- // After 30 minutes of inactivity, trigger recovery
722
- triggerCartRecovery();
723
- }, 30 * 60 * 1000);
724
- });
725
-
726
- window.addEventListener('lce:actions.checkout_submit_completed', function() {
727
- // They completed purchase - cancel recovery
728
- clearTimeout(abandonmentTimer);
729
- });
730
-
731
- function triggerCartRecovery() {
732
- // Send email, show popup, etc.
733
- console.log("Time to recover this cart!");
734
- }
735
- ```
736
-
737
- ### 📈 **Revenue Optimization**
738
- **The Goal**: Increase average order value
739
- **The Method**: Smart upselling based on behavior
740
-
741
- ```javascript
742
- window.addEventListener('lce:actions.product_add_to_cart', function(event) {
743
- const data = event.detail.data;
744
-
745
- // Offer upsells based on product identifier
746
- const upsellMap = {
747
- 'phone-001': 'phone-cases',
748
- 'laptop-001': 'laptop-accessories'
749
- };
750
-
751
- if (upsellMap[data.identifier]) {
752
- showUpsell(upsellMap[data.identifier]);
753
- }
754
-
755
- // Check if cart is close to free shipping threshold
756
- const cart = actions.cart.getDetails();
757
- if (cart.amounts.total > 45 && cart.amounts.total < 50) {
758
- showMessage("Add $" + (50 - cart.amounts.total) + " more for FREE shipping!");
759
- }
760
- });
761
- ```
762
-
763
- ### 🎯 **Conversion Tracking**
764
- **The Need**: Measure what's working
765
- **The Implementation**: Track the entire funnel
766
-
767
- ```javascript
768
- // Track the complete conversion funnel
769
- const funnelSteps = {
770
- productView: 0,
771
- addToCart: 0,
772
- cartView: 0,
773
- checkoutStart: 0,
774
- purchase: 0
775
- };
776
-
777
- window.addEventListener('lce:actions.product_loaded', () => funnelSteps.productView++);
778
- window.addEventListener('lce:actions.product_add_to_cart', () => funnelSteps.addToCart++);
779
- window.addEventListener('lce:actions.cart_opened', () => funnelSteps.cartView++);
780
- window.addEventListener('lce:actions.checkout_opened', () => funnelSteps.checkoutStart++);
781
- window.addEventListener('lce:actions.checkout_submit_completed', () => funnelSteps.purchase++);
782
-
783
- // Send to your analytics every 10 minutes
784
- setInterval(() => {
785
- console.log('Conversion Funnel:', funnelSteps);
786
- // Send to your dashboard/analytics
787
- }, 10 * 60 * 1000);
788
- ```
789
-
790
- ## Getting Started in 5 Minutes
791
-
792
- 1. **Pick one goal** from the examples above
793
- 2. **Copy the code** into your website
794
- 3. **Replace the console.log** with your actual actions (send email, show popup, etc.)
795
- 4. **Test it** by going through the flow yourself
796
- 5. **Monitor the results** and adjust as needed
797
-
798
- **Need help?** The events automatically work once LiquidCommerce Elements are on your page. Just add the JavaScript code and you're ready to go!