@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.
- package/README.md +83 -2750
- package/dist/index.checkout.esm.js +6898 -6837
- package/dist/index.esm.js +11463 -10993
- package/dist/types/auto-initialize/shared-utils.d.ts +5 -0
- package/dist/types/constants/core.constant.d.ts +0 -4
- package/dist/types/core/base-component.service.d.ts +2 -1
- package/dist/types/core/pubsub/interfaces/checkout.interface.d.ts +1 -0
- package/dist/types/enums/core.enum.d.ts +11 -0
- package/dist/types/interfaces/configs/product-list.interface.d.ts +2 -2
- package/dist/types/interfaces/core.interface.d.ts +5 -4
- package/dist/types/modules/address/address-input.component.d.ts +11 -0
- package/dist/types/modules/checkout/components/checkout-stripe-form.component.d.ts +2 -1
- package/dist/types/modules/product-list/components/card-components/index.d.ts +3 -0
- package/dist/types/modules/product-list/components/card-components/product-badge.d.ts +8 -0
- package/dist/types/modules/product-list/components/card-components/product-fulfillments.d.ts +2 -0
- package/dist/types/modules/product-list/components/card-components/product-price-and-personalization.d.ts +13 -0
- package/dist/types/modules/product-list/components/card-components/product-title.d.ts +6 -0
- package/dist/types/modules/product-list/components/index.d.ts +1 -0
- package/dist/types/modules/product-list/components/product-list-engraving.component.d.ts +5 -1
- package/dist/types/modules/product-list/components/product-list-product-pre-cart.component.d.ts +28 -0
- package/dist/types/modules/product-list/components/product-list-retailers.component.d.ts +10 -2
- package/dist/types/modules/product-list/product-list-card.component.d.ts +0 -5
- package/dist/types/modules/product-list/product-list.commands.d.ts +11 -2
- package/dist/types/modules/product-list/product-list.interface.d.ts +1 -0
- package/dist/types/modules/ui-components/engraving/engraving-form.component.d.ts +11 -2
- package/dist/types/modules/ui-components/lce-element/lce-element.component.d.ts +2 -1
- package/dist/types/utils/dom-compat.d.ts +2 -0
- package/docs/gitbook/actions.md +964 -0
- package/docs/gitbook/address.md +48 -0
- package/docs/gitbook/cart.md +65 -0
- package/docs/gitbook/checkout.md +131 -0
- package/docs/gitbook/events.md +1765 -0
- package/docs/gitbook/overview.md +166 -0
- package/docs/gitbook/product.md +64 -0
- package/docs/gitbook/quick-start-guide.md +393 -0
- package/docs/v1/README.md +210 -0
- package/docs/v1/api/actions/address-actions.md +281 -0
- package/docs/v1/api/actions/cart-actions.md +337 -0
- package/docs/v1/api/actions/checkout-actions.md +387 -0
- package/docs/v1/api/actions/product-actions.md +115 -0
- package/docs/v1/api/client.md +482 -0
- package/docs/v1/api/configuration.md +1 -0
- package/docs/v1/api/injection-methods.md +247 -0
- package/docs/v1/api/typescript-types.md +1 -0
- package/docs/v1/api/ui-helpers.md +200 -0
- package/docs/v1/examples/advanced-patterns.md +96 -0
- package/docs/v1/examples/checkout-flow.md +91 -0
- package/docs/v1/examples/custom-theming.md +63 -0
- package/docs/v1/examples/multi-product-page.md +90 -0
- package/docs/v1/examples/simple-product-page.md +89 -0
- package/docs/v1/getting-started/concepts.md +507 -0
- package/docs/v1/getting-started/installation.md +328 -0
- package/docs/v1/getting-started/quick-start.md +405 -0
- package/docs/v1/guides/address-component.md +431 -0
- package/docs/v1/guides/best-practices.md +324 -0
- package/docs/v1/guides/cart-component.md +737 -0
- package/docs/v1/guides/checkout-component.md +672 -0
- package/docs/v1/guides/events.md +926 -0
- package/docs/v1/guides/product-component.md +686 -0
- package/docs/v1/guides/product-list-component.md +598 -0
- package/docs/v1/guides/theming.md +216 -0
- package/docs/v1/integration/angular.md +39 -0
- package/docs/v1/integration/laravel.md +41 -0
- package/docs/v1/integration/nextjs.md +60 -0
- package/docs/v1/integration/proxy-setup.md +89 -0
- package/docs/v1/integration/react.md +64 -0
- package/docs/v1/integration/vanilla-js.md +84 -0
- package/docs/v1/integration/vue.md +34 -0
- package/docs/v1/reference/browser-support.md +44 -0
- package/docs/v1/reference/error-handling.md +70 -0
- package/docs/v1/reference/performance.md +54 -0
- package/docs/v1/reference/troubleshooting.md +64 -0
- package/package.json +1 -1
- package/docs/ACTIONS.md +0 -1301
- package/docs/BROWSER_SUPPORT.md +0 -279
- package/docs/CONFIGURATION.md +0 -997
- package/docs/DOCUMENTATION_INDEX.md +0 -319
- package/docs/EVENTS.md +0 -798
- package/docs/PROXY.md +0 -228
- package/docs/THEMING.md +0 -681
- 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
|