@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
@@ -0,0 +1,737 @@
1
+ # Cart Component
2
+
3
+ The Cart component provides a slide-out drawer for managing shopping cart items, applying promo codes, and proceeding to checkout.
4
+
5
+ ## Overview
6
+
7
+ The Cart component automatically:
8
+ - Displays cart items with images and details
9
+ - Groups items by retailer
10
+ - Shows real-time pricing and totals
11
+ - Supports quantity updates
12
+ - Handles promo code application
13
+ - Persists cart across sessions and tabs
14
+ - Provides checkout navigation
15
+
16
+ ## Basic Usage
17
+
18
+ The cart is automatically available when using the SDK - no explicit injection needed for the drawer. However, you need a way for users to open it.
19
+
20
+ ### Cart Buttons
21
+
22
+ #### Declarative Cart Button
23
+
24
+ Add a cart button using data attributes on the SDK script:
25
+
26
+ ```html
27
+ <script
28
+ defer
29
+ data-liquid-commerce-elements
30
+ data-token="YOUR_API_KEY"
31
+ data-env="production"
32
+ data-cart-button="header-cart"
33
+ type="text/javascript"
34
+ src="https://assets-elements.liquidcommerce.us/all/elements.js"
35
+ ></script>
36
+
37
+ <div id="header-cart"></div>
38
+ ```
39
+
40
+ #### Cart Button with Item Count Badge
41
+
42
+ Show the number of items in the cart:
43
+
44
+ ```html
45
+ <script
46
+ defer
47
+ data-liquid-commerce-elements
48
+ data-token="YOUR_API_KEY"
49
+ data-env="production"
50
+ data-cart-badge-button="header-cart"
51
+ type="text/javascript"
52
+ src="https://assets-elements.liquidcommerce.us/all/elements.js"
53
+ ></script>
54
+
55
+ <div id="header-cart"></div>
56
+ ```
57
+
58
+ #### Floating Cart Button
59
+
60
+ Create a floating button (bottom-right corner):
61
+
62
+ ```html
63
+ <script
64
+ defer
65
+ data-liquid-commerce-elements
66
+ data-token="YOUR_API_KEY"
67
+ data-env="production"
68
+ data-cart-button
69
+ type="text/javascript"
70
+ src="https://assets-elements.liquidcommerce.us/all/elements.js"
71
+ ></script>
72
+ ```
73
+
74
+ Leaving `data-cart-button` empty creates a floating button automatically.
75
+
76
+ #### Positional Cart Button
77
+
78
+ Control where the cart button appears:
79
+
80
+ ```html
81
+ <!-- Inside an element -->
82
+ <script data-cart-button="inside:#header"></script>
83
+
84
+ <!-- Above an element -->
85
+ <script data-cart-button="above:.navigation"></script>
86
+
87
+ <!-- Below an element -->
88
+ <script data-cart-button="below:#logo"></script>
89
+
90
+ <!-- Replace an element -->
91
+ <script data-cart-button="replace:#cart-placeholder"></script>
92
+ ```
93
+
94
+ #### Hide Cart Button
95
+
96
+ If you want to control cart opening manually:
97
+
98
+ ```html
99
+ <script
100
+ defer
101
+ data-liquid-commerce-elements
102
+ data-token="YOUR_API_KEY"
103
+ data-env="production"
104
+ data-cart-button-hidden
105
+ type="text/javascript"
106
+ src="https://assets-elements.liquidcommerce.us/all/elements.js"
107
+ ></script>
108
+ ```
109
+
110
+ #### Programmatic Cart Button
111
+
112
+ Create cart buttons using JavaScript:
113
+
114
+ ```javascript
115
+ // Button in a container
116
+ window.elements.ui.cartButton('my-container', false); // No badge
117
+
118
+ // Button with item count
119
+ window.elements.ui.cartButton('my-container', true); // With badge
120
+
121
+ // Floating button
122
+ window.elements.ui.floatingCartButton(true); // With badge
123
+ ```
124
+
125
+ ### Custom Toggle Buttons
126
+
127
+ Use your own button to toggle the cart:
128
+
129
+ ```html
130
+ <button data-lce-cart-toggle-button>
131
+ View Cart
132
+ </button>
133
+ ```
134
+
135
+ The SDK automatically adds click handlers to elements with `data-lce-cart-toggle-button`.
136
+
137
+ ## Cart Actions
138
+
139
+ ### Open Cart
140
+
141
+ ```javascript
142
+ window.elements.actions.cart.openCart();
143
+ ```
144
+
145
+ ### Close Cart
146
+
147
+ ```javascript
148
+ window.elements.actions.cart.closeCart();
149
+ ```
150
+
151
+ ### Toggle Cart
152
+
153
+ ```javascript
154
+ window.elements.actions.cart.toggleCart();
155
+ ```
156
+
157
+ ### Add Product to Cart
158
+
159
+ Add products programmatically:
160
+
161
+ ```javascript
162
+ await window.elements.actions.cart.addProduct([
163
+ {
164
+ identifier: '00619947000020',
165
+ fulfillmentType: 'shipping', // or 'onDemand'
166
+ quantity: 2
167
+ },
168
+ {
169
+ identifier: '08504405135',
170
+ fulfillmentType: 'onDemand',
171
+ quantity: 1
172
+ }
173
+ ], true); // true = open cart after adding
174
+ ```
175
+
176
+ **Parameters:**
177
+ - `identifier` (string): Product UPC, SKU, or ID
178
+ - `fulfillmentType` (string): `'shipping'` or `'onDemand'`
179
+ - `quantity` (number): Number of items (default: 1)
180
+ - Second parameter (boolean): Open cart after adding (default: false)
181
+
182
+ ### Apply Promo Code
183
+
184
+ ```javascript
185
+ await window.elements.actions.cart.applyPromoCode('SUMMER20');
186
+ ```
187
+
188
+ The SDK automatically:
189
+ - Validates the promo code
190
+ - Calculates discount
191
+ - Updates cart totals
192
+ - Shows success/error message
193
+
194
+ ### Remove Promo Code
195
+
196
+ ```javascript
197
+ await window.elements.actions.cart.removePromoCode();
198
+ ```
199
+
200
+ ### Reset Cart
201
+
202
+ Clear all items from the cart:
203
+
204
+ ```javascript
205
+ await window.elements.actions.cart.resetCart();
206
+ ```
207
+
208
+ ### Get Cart Details
209
+
210
+ Retrieve current cart information:
211
+
212
+ ```javascript
213
+ const cartData = window.elements.actions.cart.getDetails();
214
+
215
+ console.log(cartData);
216
+ // {
217
+ // cartId: 'cart_abc123',
218
+ // items: [...],
219
+ // subtotal: 9998, // in cents
220
+ // total: 9998,
221
+ // itemsCount: 3,
222
+ // itemsQuantity: 5,
223
+ // promoCode: { code: 'SUMMER20', discount: 1000 },
224
+ // retailers: [...],
225
+ // ...
226
+ // }
227
+ ```
228
+
229
+ ## Cart UI Helpers
230
+
231
+ ### Display Cart Subtotal
232
+
233
+ Show cart subtotal anywhere on your page:
234
+
235
+ ```html
236
+ <div>
237
+ Cart Total: <span id="cart-total"></span>
238
+ </div>
239
+
240
+ <script>
241
+ window.addEventListener('lce:actions.client_ready', () => {
242
+ window.elements.ui.cartSubtotal('cart-total');
243
+ });
244
+ </script>
245
+ ```
246
+
247
+ The element automatically updates when the cart changes.
248
+
249
+ ### Display Items Count
250
+
251
+ Show the number of items in the cart:
252
+
253
+ ```html
254
+ <div>
255
+ Items: <span id="items-count"></span>
256
+ </div>
257
+
258
+ <script>
259
+ window.addEventListener('lce:actions.client_ready', () => {
260
+ window.elements.ui.cartItemsCount('items-count', {
261
+ hideZero: true // Hide when cart is empty
262
+ });
263
+ });
264
+ </script>
265
+ ```
266
+
267
+ Or using data attributes:
268
+
269
+ ```html
270
+ <!-- Always show count, even when 0 -->
271
+ <span data-lce-cart-items-count="keep-zero"></span>
272
+
273
+ <!-- Hide when 0 (default behavior) -->
274
+ <span data-lce-cart-items-count></span>
275
+ ```
276
+
277
+ ## Events
278
+
279
+ ### Cart Loaded
280
+
281
+ Fired when cart data is loaded:
282
+
283
+ ```javascript
284
+ window.addEventListener('lce:actions.cart_loaded', (event) => {
285
+ const { cartId, itemsCount, subtotal } = event.detail.data;
286
+ console.log(`Cart loaded: ${itemsCount} items, total: $${subtotal / 100}`);
287
+ });
288
+ ```
289
+
290
+ ### Cart Opened/Closed
291
+
292
+ ```javascript
293
+ window.addEventListener('lce:actions.cart_opened', (event) => {
294
+ console.log('Cart drawer opened');
295
+ });
296
+
297
+ window.addEventListener('lce:actions.cart_closed', (event) => {
298
+ console.log('Cart drawer closed');
299
+ });
300
+ ```
301
+
302
+ ### Cart Updated
303
+
304
+ Fired whenever cart contents change:
305
+
306
+ ```javascript
307
+ window.addEventListener('lce:actions.cart_updated', (event) => {
308
+ const { cartId, itemsCount, subtotal } = event.detail.data;
309
+ console.log('Cart updated:', itemsCount, 'items');
310
+ });
311
+ ```
312
+
313
+ ### Item Added
314
+
315
+ ```javascript
316
+ window.addEventListener('lce:actions.cart_item_added', (event) => {
317
+ const { cartId, itemId, quantity } = event.detail.data;
318
+ console.log(`Item ${itemId} added (quantity: ${quantity})`);
319
+ });
320
+ ```
321
+
322
+ ### Item Removed
323
+
324
+ ```javascript
325
+ window.addEventListener('lce:actions.cart_item_removed', (event) => {
326
+ const { cartId, itemId } = event.detail.data;
327
+ console.log(`Item ${itemId} removed`);
328
+ });
329
+ ```
330
+
331
+ ### Quantity Changed
332
+
333
+ ```javascript
334
+ window.addEventListener('lce:actions.cart_item_quantity_increase', (event) => {
335
+ const { cartId, itemId, newQuantity } = event.detail.data;
336
+ console.log(`Item ${itemId} quantity increased to ${newQuantity}`);
337
+ });
338
+
339
+ window.addEventListener('lce:actions.cart_item_quantity_decrease', (event) => {
340
+ const { cartId, itemId, newQuantity } = event.detail.data;
341
+ console.log(`Item ${itemId} quantity decreased to ${newQuantity}`);
342
+ });
343
+ ```
344
+
345
+ ### Promo Code Events
346
+
347
+ ```javascript
348
+ window.addEventListener('lce:actions.cart_promo_code_applied', (event) => {
349
+ const { cartId, discount, newSubtotal } = event.detail.data;
350
+ console.log(`Promo code applied: $${discount / 100} off`);
351
+ });
352
+
353
+ window.addEventListener('lce:actions.cart_promo_code_removed', (event) => {
354
+ const { cartId, newSubtotal } = event.detail.data;
355
+ console.log('Promo code removed');
356
+ });
357
+
358
+ window.addEventListener('lce:actions.cart_promo_code_failed', (event) => {
359
+ const { cartId, error } = event.detail.data;
360
+ console.error('Promo code failed:', error);
361
+ });
362
+ ```
363
+
364
+ ### Product Add Success/Failure
365
+
366
+ ```javascript
367
+ window.addEventListener('lce:actions.cart_product_add_success', (event) => {
368
+ const { cartId, itemsAdded, identifiers } = event.detail.data;
369
+ console.log(`Successfully added ${itemsAdded} products`);
370
+ });
371
+
372
+ window.addEventListener('lce:actions.cart_product_add_failed', (event) => {
373
+ const { cartId, identifiers, error } = event.detail.data;
374
+ console.error('Failed to add products:', error);
375
+ });
376
+ ```
377
+
378
+ ### Cart Reset
379
+
380
+ ```javascript
381
+ window.addEventListener('lce:actions.cart_reset', (event) => {
382
+ console.log('Cart has been reset');
383
+ });
384
+ ```
385
+
386
+ ## Customization
387
+
388
+ ### Theme Configuration
389
+
390
+ Customize cart appearance:
391
+
392
+ ```javascript
393
+ const client = await Elements('YOUR_API_KEY', {
394
+ env: 'production',
395
+ customTheme: {
396
+ cart: {
397
+ theme: {
398
+ backgroundColor: '#ffffff'
399
+ },
400
+ layout: {
401
+ showQuantityCounter: true,
402
+ quantityCounterStyle: 'outlined', // or 'input'
403
+ drawerHeaderText: 'My Bag',
404
+ goToCheckoutButtonText: 'Checkout'
405
+ }
406
+ }
407
+ }
408
+ });
409
+ ```
410
+
411
+ ## State Persistence
412
+
413
+ ### Local Storage
414
+
415
+ The cart automatically persists to `localStorage`
416
+
417
+ This allows the cart to survive:
418
+ - Page refreshes
419
+ - Browser restarts
420
+ - Navigation between pages
421
+
422
+ ### Cross-Tab Synchronization
423
+
424
+ When you update the cart in one tab, all other open tabs automatically sync:
425
+
426
+ ```javascript
427
+ // Tab 1: Add item
428
+ await window.elements.actions.cart.addProduct([...]);
429
+
430
+ // Tab 2: Cart automatically updates
431
+ // No additional code needed
432
+ ```
433
+
434
+ The SDK uses the following mechanisms:
435
+ - localStorage events
436
+ - Periodic polling
437
+ - API-based fallback
438
+
439
+ ### Session Duration
440
+
441
+ Carts persist for 45 days by default. After 45 days of inactivity, the cart is cleared.
442
+
443
+ ## Address Requirement
444
+
445
+ The cart requires a delivery address for:
446
+ - Accurate availability
447
+ - Correct pricing
448
+ - Shipping calculations
449
+
450
+ ### Automatic Address Prompt
451
+
452
+ If no address is set when adding to cart, the SDK:
453
+ 1. Opens address input drawer
454
+ 2. Waits for user to set address
455
+ 3. Retries the add-to-cart operation
456
+
457
+ ### Pre-set Address
458
+
459
+ Set address before adding to cart:
460
+
461
+ ```javascript
462
+ await window.elements.actions.address.setAddressByPlacesId('ChIJ...');
463
+
464
+ // Now add to cart
465
+ await window.elements.actions.cart.addProduct([...]);
466
+ ```
467
+
468
+ ## Promo Codes
469
+
470
+ ### Configuration
471
+
472
+ Enable/disable promo codes globally:
473
+
474
+ ```javascript
475
+ customTheme: {
476
+ global: {
477
+ layout: {
478
+ allowPromoCodes: true // or false to disable
479
+ }
480
+ }
481
+ }
482
+ ```
483
+
484
+ ### Promo Ticker
485
+
486
+ Show promotional codes in a scrolling ticker:
487
+
488
+ ```javascript
489
+ const client = await Elements('YOUR_API_KEY', {
490
+ env: 'production',
491
+ promoTicker: [
492
+ {
493
+ promoCode: 'SUMMER20',
494
+ text: ['20% Off Summer Sale', 'Free Shipping on Orders Over $50'],
495
+ separator: '•',
496
+ activeFrom: '2024-06-01T00:00:00Z',
497
+ activeUntil: '2024-08-31T23:59:59Z'
498
+ }
499
+ ]
500
+ });
501
+ ```
502
+
503
+ Or with data attributes:
504
+
505
+ ```html
506
+ <script
507
+ defer
508
+ data-liquid-commerce-elements
509
+ data-token="YOUR_API_KEY"
510
+ data-env="production"
511
+ data-promo-code="SUMMER20"
512
+ data-promo-text="20% Off Summer Sale | Free Shipping on Orders Over $50"
513
+ data-promo-separator="•"
514
+ data-promo-active-from="2024-06-01T00:00:00Z"
515
+ data-promo-active-until="2024-08-31T23:59:59Z"
516
+ type="text/javascript"
517
+ src="https://assets-elements.liquidcommerce.us/all/elements.js"
518
+ ></script>
519
+ ```
520
+
521
+ ### Auto-Apply from URL
522
+
523
+ Apply promo codes automatically via URL parameters:
524
+
525
+ ```html
526
+ <script
527
+ defer
528
+ data-liquid-commerce-elements
529
+ data-token="YOUR_API_KEY"
530
+ data-env="production"
531
+ data-promo-code-param="lce_promo"
532
+ type="text/javascript"
533
+ src="https://assets-elements.liquidcommerce.us/all/elements.js"
534
+ ></script>
535
+ ```
536
+
537
+ Now visiting `https://yoursite.com?lce_promo=SUMMER20` automatically applies the code.
538
+
539
+ **Security Note:** Query parameters must start with `lce_` prefix to prevent conflicts with your application.
540
+
541
+ ## Retailer Grouping
542
+
543
+ Items are automatically grouped by retailer in the cart:
544
+
545
+ ```
546
+ ┌─────────────────────────────────────┐
547
+ │ Cart (3 items) │
548
+ ├─────────────────────────────────────┤
549
+ │ Spirits Shop │
550
+ │ • Premium Whiskey (750ml) $49 │
551
+ │ • Bourbon Bottle (1L) $65 │
552
+ │ │
553
+ │ Wine & More │
554
+ │ • Red Wine (750ml) $25 │
555
+ ├─────────────────────────────────────┤
556
+ │ Subtotal: $139 │
557
+ │ Promo Code (SUMMER20): -$28 │
558
+ │ Total: $111 │
559
+ └─────────────────────────────────────┘
560
+ ```
561
+
562
+ ## Checkout Navigation
563
+
564
+ ### Checkout Drawer (Default)
565
+
566
+ By default, clicking "Checkout" opens the checkout drawer:
567
+
568
+ ```javascript
569
+ // User clicks checkout
570
+ // Checkout drawer slides in
571
+ ```
572
+
573
+ ### Checkout Page (Custom URL)
574
+
575
+ Redirect to a custom checkout page:
576
+
577
+ ```javascript
578
+ const client = await Elements('YOUR_API_KEY', {
579
+ env: 'production',
580
+ checkout: {
581
+ pageUrl: 'https://yoursite.com/checkout/{token}'
582
+ }
583
+ });
584
+ ```
585
+
586
+ Or with data attributes:
587
+
588
+ ```html
589
+ <script
590
+ defer
591
+ data-liquid-commerce-elements
592
+ data-token="YOUR_API_KEY"
593
+ data-env="production"
594
+ data-checkout-url="https://yoursite.com/checkout/{token}"
595
+ type="text/javascript"
596
+ src="https://assets-elements.liquidcommerce.us/all/elements.js"
597
+ ></script>
598
+ ```
599
+
600
+ The `{token}` placeholder is replaced with the session checkout token.
601
+
602
+ ## Use Cases
603
+
604
+ ### E-commerce Site
605
+
606
+ ```javascript
607
+ // Track cart events for analytics
608
+ window.addEventListener('lce:actions.cart_item_added', (event) => {
609
+ gtag('event', 'add_to_cart', {
610
+ value: event.detail.data.price / 100,
611
+ currency: 'USD'
612
+ });
613
+ });
614
+
615
+ window.addEventListener('lce:actions.cart_updated', (event) => {
616
+ // Update header cart count
617
+ document.getElementById('cart-badge').textContent =
618
+ event.detail.data.itemsCount;
619
+ });
620
+ ```
621
+
622
+ ### Marketing Campaign
623
+
624
+ ```javascript
625
+ // Check URL for campaign parameter
626
+ const params = new URLSearchParams(window.location.search);
627
+ const campaign = params.get('campaign');
628
+
629
+ if (campaign === 'summer-sale') {
630
+ await window.elements.actions.cart.applyPromoCode('SUMMER20');
631
+ window.elements.actions.cart.openCart();
632
+ }
633
+ ```
634
+
635
+ ### Abandoned Cart Recovery
636
+
637
+ ```javascript
638
+ // Store cart ID in your system
639
+ window.addEventListener('lce:actions.cart_updated', (event) => {
640
+ const { cartId, itemsCount } = event.detail.data;
641
+
642
+ if (itemsCount > 0) {
643
+ // Send cart ID to your backend for abandoned cart emails
644
+ fetch('/api/track-cart', {
645
+ method: 'POST',
646
+ body: JSON.stringify({ cartId, userId: currentUserId })
647
+ });
648
+ }
649
+ });
650
+ ```
651
+
652
+ ## Best Practices
653
+
654
+ ### Initialize Cart Early
655
+
656
+ Pre-load cart on page load for faster access:
657
+
658
+ ```javascript
659
+ window.addEventListener('lce:actions.client_ready', () => {
660
+ // Cart loads automatically, but you can pre-fetch if needed
661
+ window.elements.actions.cart.getDetails();
662
+ });
663
+ ```
664
+
665
+ ### Provide Visual Feedback
666
+
667
+ Show loading states when adding to cart:
668
+
669
+ ```javascript
670
+ async function addToCart(productId) {
671
+ const button = document.getElementById('add-to-cart-btn');
672
+ button.disabled = true;
673
+ button.textContent = 'Adding...';
674
+
675
+ try {
676
+ await window.elements.actions.cart.addProduct([
677
+ { identifier: productId, fulfillmentType: 'shipping', quantity: 1 }
678
+ ], true);
679
+
680
+ button.textContent = 'Added!';
681
+ setTimeout(() => {
682
+ button.disabled = false;
683
+ button.textContent = 'Add to Cart';
684
+ }, 2000);
685
+ } catch (error) {
686
+ button.textContent = 'Failed';
687
+ button.disabled = false;
688
+ }
689
+ }
690
+ ```
691
+
692
+ ### Handle Empty Cart
693
+
694
+ Show appropriate messaging for empty carts:
695
+
696
+ ```javascript
697
+ window.addEventListener('lce:actions.cart_updated', (event) => {
698
+ const { itemsCount } = event.detail.data;
699
+
700
+ if (itemsCount === 0) {
701
+ // Show empty state in your UI
702
+ document.getElementById('cart-status').textContent =
703
+ 'Your cart is empty';
704
+ }
705
+ });
706
+ ```
707
+
708
+ ## Troubleshooting
709
+
710
+ ### Cart Not Opening
711
+
712
+ 1. Check that SDK is initialized: `console.log(window.elements)`
713
+ 2. Verify no JavaScript errors in console
714
+ 3. Ensure cart button is properly configured
715
+ 4. Try manually: `window.elements.actions.cart.openCart()`
716
+
717
+ ### Items Not Adding
718
+
719
+ 1. Check that address is set: `window.elements.actions.address.getDetails()`
720
+ 2. Verify product identifier is valid
721
+ 3. Check fulfillment type is available for the product
722
+ 4. Look for errors in browser console
723
+
724
+ ### Promo Code Not Working
725
+
726
+ 1. Verify promo codes are enabled in configuration
727
+ 2. Check code is valid and active
728
+ 3. Ensure code hasn't already been applied
729
+ 4. Check console for error messages
730
+
731
+ ## See Also
732
+
733
+ - [Product Component](./product-component.md) - Add products to cart
734
+ - [Checkout Component](./checkout-component.md) - Complete purchase
735
+ - [Actions API](../api/actions/cart-actions.md) - Cart actions reference
736
+ - [Events](./events.md) - All available events
737
+ - [Theming](./theming.md) - Customize appearance