@liquidcommerce/elements-sdk 2.2.0-beta.3 → 2.2.0-beta.30
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 +1626 -571
- package/dist/index.esm.js +10292 -8153
- package/dist/types/core/auth.service.d.ts +10 -4
- package/dist/types/core/base-component.service.d.ts +3 -0
- package/dist/types/core/circuit-breaker.service.d.ts +54 -0
- package/dist/types/core/client/client-action.service.d.ts +15 -13
- package/dist/types/core/client/client-config.service.d.ts +5 -3
- package/dist/types/core/command/common-command.service.d.ts +2 -1
- package/dist/types/core/debug-panel/debug-panel.service.d.ts +43 -0
- package/dist/types/core/debug-panel/debug-panel.styles.d.ts +1 -0
- package/dist/types/core/fingerprint.service.d.ts +4 -9
- package/dist/types/core/google-tag-manager.service.d.ts +127 -2
- package/dist/types/core/logger/logger-factory.d.ts +3 -0
- package/dist/types/core/logger/logger.service.d.ts +8 -5
- package/dist/types/core/pubsub/interfaces/cart.interface.d.ts +1 -0
- package/dist/types/core/pubsub/interfaces/checkout.interface.d.ts +44 -6
- package/dist/types/core/pubsub/interfaces/core.interface.d.ts +2 -3
- package/dist/types/core/pubsub/interfaces/product.interface.d.ts +43 -6
- package/dist/types/core/store/interfaces/cart.interface.d.ts +1 -1
- package/dist/types/core/store/interfaces/checkout.interface.d.ts +0 -1
- package/dist/types/core/store/interfaces/core.interface.d.ts +2 -2
- package/dist/types/core/store/interfaces/product.interface.d.ts +18 -7
- package/dist/types/core/store/store.service.d.ts +1 -0
- package/dist/types/core/telemetry/telemetry.interface.d.ts +80 -0
- package/dist/types/core/telemetry/telemetry.service.d.ts +27 -0
- package/dist/types/enums/core.enum.d.ts +0 -1
- package/dist/types/enums/debug.enum.d.ts +6 -0
- package/dist/types/enums/index.d.ts +1 -0
- package/dist/types/interfaces/cloud/product.interface.d.ts +2 -0
- package/dist/types/interfaces/core.interface.d.ts +2 -2
- package/dist/types/modules/address/address.command.d.ts +1 -3
- package/dist/types/modules/cart/cart.commands.d.ts +1 -1
- package/dist/types/modules/cart/cart.component.d.ts +1 -2
- package/dist/types/modules/cart/components/cart-footer.component.d.ts +1 -0
- package/dist/types/modules/cart/components/cart-item.component.d.ts +2 -6
- package/dist/types/modules/checkout/checkout.commands.d.ts +3 -2
- package/dist/types/modules/checkout/checkout.component.d.ts +1 -2
- package/dist/types/modules/checkout/components/checkout-summary-section.component.d.ts +2 -0
- package/dist/types/modules/checkout/components/information/checkout-delivery-information-form.component.d.ts +1 -1
- package/dist/types/modules/checkout/components/summary/checkout-item-quantity.component.d.ts +0 -2
- package/dist/types/modules/checkout/components/summary/checkout-item.component.d.ts +2 -1
- package/dist/types/modules/checkout/components/summary/checkout-items.component.d.ts +1 -0
- package/dist/types/modules/checkout/components/summary/checkout-place-order-button.component.d.ts +0 -1
- package/dist/types/modules/checkout/constant.d.ts +0 -1
- package/dist/types/modules/product/components/index.d.ts +1 -0
- package/dist/types/modules/product/components/product-add-to-cart-section.component.d.ts +1 -0
- package/dist/types/modules/product/components/product-interactions.component.d.ts +4 -1
- package/dist/types/modules/product/components/product-price.component.d.ts +1 -0
- package/dist/types/modules/product/components/product-retailers.component.d.ts +1 -0
- package/dist/types/modules/product/product.commands.d.ts +1 -1
- package/dist/types/modules/ui-components/engraving/engraving-form.component.d.ts +13 -11
- package/dist/types/modules/ui-components/engraving/engraving-view.component.d.ts +4 -9
- package/dist/types/static/icon/index.d.ts +0 -1
- package/dist/types/utils/format.d.ts +2 -1
- package/docs/ACTIONS.md +1237 -0
- package/docs/BROWSER_SUPPORT.md +279 -0
- package/docs/CONFIGURATION.md +613 -0
- package/docs/DOCUMENTATION_INDEX.md +311 -0
- package/docs/EVENTS.md +765 -0
- package/docs/PROXY.md +228 -0
- package/docs/THEMING.md +592 -0
- package/docs/TROUBLESHOOTING.md +755 -0
- package/package.json +17 -17
- package/umd/elements.js +1 -1
- package/dist/types/static/icon/completed.icon.d.ts +0 -2
package/README.md
CHANGED
|
@@ -28,48 +28,20 @@ Elements SDK
|
|
|
28
28
|
<summary>Click to expand</summary>
|
|
29
29
|
|
|
30
30
|
- [Overview](#-overview)
|
|
31
|
-
- [Latest Features](#-latest-features)
|
|
32
|
-
- [Key Features](#-key-features)
|
|
33
|
-
- [Architecture](#-architecture)
|
|
34
|
-
- [System Architecture](#system-architecture)
|
|
35
|
-
- [Component Architecture](#component-architecture)
|
|
36
|
-
- [Event Flow](#event-flow)
|
|
37
|
-
- [Features](#-features)
|
|
38
|
-
- [Installation](#-installation)
|
|
39
|
-
- [CDN Usage](#option-a--use-the-cdn)
|
|
40
|
-
- [NPM Installation](#option-b--install-from-npm)
|
|
41
|
-
- [Browser Support](#-browser-support)
|
|
42
31
|
- [Quick Start](#-quick-start)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
32
|
+
- [Advanced Usage](#-advanced-usage)
|
|
33
|
+
- [Browser Support](#-browser-support)
|
|
34
|
+
- [Configuration](#-configuration)
|
|
46
35
|
- [SDK Methods & API](#-sdk-methods--api)
|
|
47
|
-
- [Core Client Methods](#core-client-methods)
|
|
48
|
-
- [UI Methods](#ui-methods)
|
|
49
|
-
- [Builder Methods](#builder-methods-development-mode)
|
|
50
36
|
- [Actions](#-actions)
|
|
51
|
-
- [Product Actions](#product-actions)
|
|
52
|
-
- [Address Actions](#address-actions)
|
|
53
|
-
- [Cart Actions](#cart-actions)
|
|
54
|
-
- [Checkout Actions](#checkout-actions)
|
|
55
37
|
- [Events](#-events)
|
|
56
|
-
- [Event Listening](#event-listening)
|
|
57
|
-
- [Available Events](#available-events)
|
|
58
|
-
- [Configuration](#-configuration)
|
|
59
|
-
- [Module Options](#module-options)
|
|
60
|
-
- [Environment Options](#environment-options)
|
|
61
|
-
- [Auto-init Attributes](#auto-init-data-attributes)
|
|
62
38
|
- [Themes & Customization](#-themes--customization)
|
|
63
|
-
|
|
64
|
-
|
|
39
|
+
- [Features Deep Dive](#-features-deep-dive)
|
|
40
|
+
- [Core Capabilities](#-core-capabilities)
|
|
41
|
+
- [Integration Patterns](#-integration-patterns)
|
|
42
|
+
- [Error Handling](#-error-handling)
|
|
43
|
+
- [Performance & Best Practices](#-performance--best-practices)
|
|
65
44
|
- [Proxy Configuration](#-proxy-configuration)
|
|
66
|
-
- [Demo Pages](#-demo-pages)
|
|
67
|
-
- [Simple Demo](#simple-demo-demosimplehtml)
|
|
68
|
-
- [Advanced Demo](#advanced-demo-demoadvancedhtml)
|
|
69
|
-
- [Development Scripts](#-development-scripts)
|
|
70
|
-
- [Build Commands](#build-commands)
|
|
71
|
-
- [Code Quality](#code-quality-commands)
|
|
72
|
-
- [Maintenance](#maintenance-commands)
|
|
73
45
|
- [Documentation](#-documentation)
|
|
74
46
|
- [Versioning](#-versioning)
|
|
75
47
|
- [Support](#-support)
|
|
@@ -80,14 +52,6 @@ Elements SDK
|
|
|
80
52
|
|
|
81
53
|
The LiquidCommerce Elements SDK is a **production-ready JavaScript library** that enables partners to seamlessly integrate product displays, shopping carts, and checkout flows into any website. Built with performance and developer experience in mind.
|
|
82
54
|
|
|
83
|
-
### 🆕 Latest Features
|
|
84
|
-
|
|
85
|
-
- **Builder Mode**: Dynamic theme customization for development environments
|
|
86
|
-
- **Action Feedback Events**: All actions now emit success/failure events for better UX
|
|
87
|
-
- **Proxy Support**: Route API requests through your server to avoid ad blockers
|
|
88
|
-
- **Enhanced CLI**: Improved development scripts with parallel builds and better error handling
|
|
89
|
-
- **TypeScript Support**: Full TypeScript definitions for better IDE experience
|
|
90
|
-
|
|
91
55
|
### ✨ Key Features
|
|
92
56
|
|
|
93
57
|
<table>
|
|
@@ -133,399 +97,550 @@ The LiquidCommerce Elements SDK is a **production-ready JavaScript library** tha
|
|
|
133
97
|
</tr>
|
|
134
98
|
</table>
|
|
135
99
|
|
|
136
|
-
##
|
|
137
|
-
|
|
138
|
-
### System Architecture
|
|
139
|
-
|
|
140
|
-
```mermaid
|
|
141
|
-
graph TB
|
|
142
|
-
subgraph "Your Website"
|
|
143
|
-
HTML[HTML Page]
|
|
144
|
-
JS[JavaScript]
|
|
145
|
-
INIT[Elements SDK]
|
|
146
|
-
end
|
|
147
|
-
|
|
148
|
-
subgraph "Elements SDK Core"
|
|
149
|
-
CLIENT[Elements Client]
|
|
150
|
-
|
|
151
|
-
subgraph "Components"
|
|
152
|
-
PROD[Product Component]
|
|
153
|
-
CART[Cart Component]
|
|
154
|
-
CHECK[Checkout Component]
|
|
155
|
-
ADDR[Address Component]
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
subgraph "Services"
|
|
159
|
-
ACT[Actions Service]
|
|
160
|
-
EVT[Events Service]
|
|
161
|
-
API[API Client]
|
|
162
|
-
THEME[Theme Provider]
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
subgraph "UI Layer"
|
|
166
|
-
BTN[Cart Button]
|
|
167
|
-
FLOAT[Floating Cart]
|
|
168
|
-
DISP[Live Displays]
|
|
169
|
-
end
|
|
170
|
-
end
|
|
171
|
-
|
|
172
|
-
subgraph "LiquidCommerce API"
|
|
173
|
-
PAPI[Products API]
|
|
174
|
-
CAPI[Cart API]
|
|
175
|
-
OAPI[Orders API]
|
|
176
|
-
AAPI[Address API]
|
|
177
|
-
end
|
|
178
|
-
|
|
179
|
-
HTML --> INIT
|
|
180
|
-
JS --> CLIENT
|
|
181
|
-
|
|
182
|
-
CLIENT --> PROD
|
|
183
|
-
CLIENT --> CART
|
|
184
|
-
CLIENT --> CHECK
|
|
185
|
-
CLIENT --> ADDR
|
|
186
|
-
|
|
187
|
-
PROD --> API
|
|
188
|
-
CART --> API
|
|
189
|
-
CHECK --> API
|
|
190
|
-
ADDR --> API
|
|
191
|
-
|
|
192
|
-
API --> PAPI
|
|
193
|
-
API --> CAPI
|
|
194
|
-
API --> OAPI
|
|
195
|
-
API --> AAPI
|
|
196
|
-
|
|
197
|
-
ACT --> EVT
|
|
198
|
-
CLIENT --> ACT
|
|
199
|
-
CLIENT --> THEME
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
### Component Architecture
|
|
203
|
-
|
|
204
|
-
```mermaid
|
|
205
|
-
graph LR
|
|
206
|
-
subgraph "Product Component"
|
|
207
|
-
PD[Product Display]
|
|
208
|
-
PS[Size Selector]
|
|
209
|
-
PQ[Quantity Control]
|
|
210
|
-
PA[Add to Cart]
|
|
211
|
-
end
|
|
212
|
-
|
|
213
|
-
subgraph "Cart Component"
|
|
214
|
-
CI[Cart Items]
|
|
215
|
-
CQ[Quantity Update]
|
|
216
|
-
CP[Promo Code]
|
|
217
|
-
CT[Cart Total]
|
|
218
|
-
end
|
|
219
|
-
|
|
220
|
-
subgraph "Checkout Component"
|
|
221
|
-
CS[Shipping Info]
|
|
222
|
-
CB[Billing Info]
|
|
223
|
-
PM[Payment Method]
|
|
224
|
-
OS[Order Summary]
|
|
225
|
-
end
|
|
226
|
-
|
|
227
|
-
PD --> PS
|
|
228
|
-
PS --> PQ
|
|
229
|
-
PQ --> PA
|
|
230
|
-
|
|
231
|
-
CI --> CQ
|
|
232
|
-
CQ --> CT
|
|
233
|
-
CP --> CT
|
|
234
|
-
|
|
235
|
-
CS --> CB
|
|
236
|
-
CB --> PM
|
|
237
|
-
PM --> OS
|
|
238
|
-
```
|
|
239
|
-
|
|
240
|
-
### Event Flow
|
|
241
|
-
|
|
242
|
-
```mermaid
|
|
243
|
-
sequenceDiagram
|
|
244
|
-
participant User
|
|
245
|
-
participant SDK
|
|
246
|
-
participant Actions
|
|
247
|
-
participant Events
|
|
248
|
-
participant API
|
|
249
|
-
participant Website
|
|
250
|
-
|
|
251
|
-
User->>SDK: Add to Cart
|
|
252
|
-
SDK->>Actions: cart.addProduct()
|
|
253
|
-
Actions->>API: POST /cart/items
|
|
254
|
-
API-->>Actions: Response
|
|
255
|
-
Actions->>Events: Emit Success/Failure
|
|
256
|
-
Events->>Website: lce:actions.cart_product_add_success
|
|
257
|
-
Website->>User: Show Feedback
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
## 🚀 Features
|
|
261
|
-
|
|
262
|
-
- **🎯 Auto-initialization**: Single script tag with data attributes
|
|
263
|
-
- **📦 Zero Dependencies**: Everything bundled, no peer dependencies
|
|
264
|
-
- **🌐 CDN Ready**: No build step required for basic usage
|
|
265
|
-
- **⚡ Lightweight**: ~150KB minified bundle size
|
|
266
|
-
- **🔧 Framework Agnostic**: Works with React, Vue, Angular, or vanilla JS
|
|
267
|
-
- **📱 Responsive**: Mobile-first design approach
|
|
268
|
-
- **♿ Accessible**: WCAG 2.1 AA compliant components
|
|
269
|
-
- **🎨 Themeable**: Comprehensive customization system
|
|
270
|
-
- **🔐 Secure**: PCI compliant checkout flow
|
|
271
|
-
- **📊 Analytics Ready**: Built-in event system for tracking
|
|
272
|
-
- **🌍 Multi-environment**: Support for dev, staging, and production
|
|
273
|
-
- **🧪 Well Tested**: Comprehensive test coverage
|
|
274
|
-
|
|
275
|
-
## 📦 Installation
|
|
276
|
-
|
|
277
|
-
### Choose how to include the SDK
|
|
278
|
-
|
|
279
|
-
- **Use our CDN** (no build step required)
|
|
280
|
-
- **Install from NPM** (for bundlers like Vite, Webpack, etc.)
|
|
281
|
-
|
|
282
|
-
### Option A — Use the CDN
|
|
283
|
-
|
|
284
|
-
Include the script on your page. Use the production or beta URL:
|
|
100
|
+
## 🚀 Quick Start
|
|
285
101
|
|
|
286
|
-
|
|
287
|
-
<!-- Production (latest) -->
|
|
288
|
-
<script src="https://assets-elements.liquidcommerce.us/all/elements.js"></script>
|
|
102
|
+
The fastest way to add e-commerce to your site is with **auto-initialization** - a single script tag that does everything.
|
|
289
103
|
|
|
290
|
-
|
|
291
|
-
<script src="https://assets-elements.liquidcommerce.us/all/beta/elements.js"></script>
|
|
292
|
-
```
|
|
104
|
+
### The Simplest Setup (30 seconds)
|
|
293
105
|
|
|
294
|
-
|
|
106
|
+
Add this single script tag to your page:
|
|
295
107
|
|
|
296
108
|
```html
|
|
297
|
-
<script
|
|
109
|
+
<script
|
|
110
|
+
data-liquid-commerce-elements
|
|
111
|
+
data-token="YOUR_API_KEY"
|
|
112
|
+
data-env="production"
|
|
113
|
+
src="https://assets-elements.liquidcommerce.us/all/elements.js"
|
|
114
|
+
></script>
|
|
298
115
|
```
|
|
299
116
|
|
|
300
|
-
|
|
117
|
+
That's it! You now have:
|
|
118
|
+
- ✅ A floating cart button (bottom right)
|
|
119
|
+
- ✅ Full cart functionality
|
|
120
|
+
- ✅ Complete checkout flow
|
|
121
|
+
- ✅ Ready to add products
|
|
301
122
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
123
|
+
### Adding Products to Your Page
|
|
124
|
+
|
|
125
|
+
Now let's display products. Choose the method that fits your use case:
|
|
126
|
+
|
|
127
|
+
#### Method 1: Direct Attributes (Best for static pages)
|
|
128
|
+
|
|
129
|
+
Add products directly in the script tag:
|
|
130
|
+
|
|
131
|
+
```html
|
|
132
|
+
<div id="product-1"></div>
|
|
133
|
+
<div id="product-2"></div>
|
|
134
|
+
|
|
135
|
+
<script
|
|
136
|
+
data-liquid-commerce-elements
|
|
137
|
+
data-token="YOUR_API_KEY"
|
|
138
|
+
data-env="production"
|
|
139
|
+
data-container-1="product-1"
|
|
140
|
+
data-product-1="00619947000020"
|
|
141
|
+
data-container-2="product-2"
|
|
142
|
+
data-product-2="00832889005513"
|
|
143
|
+
src="https://assets-elements.liquidcommerce.us/all/elements.js"
|
|
144
|
+
></script>
|
|
306
145
|
```
|
|
307
146
|
|
|
308
|
-
|
|
147
|
+
**Use case:** Static HTML pages with known products
|
|
309
148
|
|
|
310
|
-
|
|
311
|
-
import { Elements } from '@liquidcommerceteam/elements-sdk';
|
|
149
|
+
#### Method 2: JSON Configuration (Best for CMS/dynamic content)
|
|
312
150
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
151
|
+
Configure products via a JSON script block:
|
|
152
|
+
|
|
153
|
+
```html
|
|
154
|
+
<div id="product-1"></div>
|
|
155
|
+
<div id="product-2"></div>
|
|
156
|
+
|
|
157
|
+
<script data-liquid-commerce-elements-products type="application/json">
|
|
158
|
+
[
|
|
159
|
+
{ "containerId": "product-1", "identifier": "00619947000020" },
|
|
160
|
+
{ "containerId": "product-2", "identifier": "00832889005513" }
|
|
161
|
+
]
|
|
162
|
+
</script>
|
|
163
|
+
|
|
164
|
+
<script
|
|
165
|
+
data-liquid-commerce-elements
|
|
166
|
+
data-token="YOUR_API_KEY"
|
|
167
|
+
data-env="production"
|
|
168
|
+
src="https://assets-elements.liquidcommerce.us/all/elements.js"
|
|
169
|
+
></script>
|
|
316
170
|
```
|
|
317
171
|
|
|
318
|
-
|
|
172
|
+
**Use case:** CMS platforms, templating engines, server-side rendering
|
|
319
173
|
|
|
320
|
-
|
|
174
|
+
#### Method 3: Annotated Elements (Best for grids/lists)
|
|
321
175
|
|
|
322
|
-
|
|
176
|
+
Mark any div with a data attribute:
|
|
323
177
|
|
|
324
|
-
|
|
178
|
+
```html
|
|
179
|
+
<div class="product-grid">
|
|
180
|
+
<div data-lce-product="00619947000020"></div>
|
|
181
|
+
<div data-lce-product="00832889005513"></div>
|
|
182
|
+
<div data-lce-product="00851468007252"></div>
|
|
183
|
+
</div>
|
|
325
184
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
185
|
+
<script
|
|
186
|
+
data-liquid-commerce-elements
|
|
187
|
+
data-token="YOUR_API_KEY"
|
|
188
|
+
data-env="production"
|
|
189
|
+
src="https://assets-elements.liquidcommerce.us/all/elements.js"
|
|
190
|
+
></script>
|
|
191
|
+
```
|
|
333
192
|
|
|
334
|
-
|
|
193
|
+
**Use case:** Product grids, category pages, search results
|
|
335
194
|
|
|
336
|
-
|
|
195
|
+
### Customizing the Cart Button
|
|
337
196
|
|
|
338
|
-
|
|
197
|
+
By default, you get a floating cart button. Here's how to customize it:
|
|
339
198
|
|
|
340
|
-
|
|
341
|
-
- At the end of the `<body>` (recommended), or
|
|
342
|
-
- In the `<head>` with `defer` so it doesn't block rendering.
|
|
199
|
+
#### Option 1: Cart Button in a Specific Container
|
|
343
200
|
|
|
344
201
|
```html
|
|
345
|
-
|
|
202
|
+
<nav>
|
|
203
|
+
<div id="header-cart"></div>
|
|
204
|
+
</nav>
|
|
205
|
+
|
|
346
206
|
<script
|
|
347
207
|
data-liquid-commerce-elements
|
|
348
208
|
data-token="YOUR_API_KEY"
|
|
349
209
|
data-env="production"
|
|
350
|
-
data-cart-id="
|
|
210
|
+
data-cart-id="header-cart"
|
|
351
211
|
data-show-cart-items
|
|
352
212
|
src="https://assets-elements.liquidcommerce.us/all/elements.js"
|
|
353
213
|
></script>
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
#### Option 2: No Cart Button (Manual Control)
|
|
354
217
|
|
|
355
|
-
|
|
218
|
+
```html
|
|
356
219
|
<script
|
|
357
|
-
defer
|
|
358
220
|
data-liquid-commerce-elements
|
|
359
221
|
data-token="YOUR_API_KEY"
|
|
360
222
|
data-env="production"
|
|
361
|
-
data-cart-
|
|
362
|
-
data-show-cart-items
|
|
223
|
+
data-hide-cart-floating-button
|
|
363
224
|
src="https://assets-elements.liquidcommerce.us/all/elements.js"
|
|
364
225
|
></script>
|
|
365
226
|
```
|
|
366
227
|
|
|
367
|
-
|
|
368
|
-
- `data-token="YOUR_API_KEY"` - Your API key (required)
|
|
369
|
-
- `data-env="production|development"` - Environment (default: production)
|
|
370
|
-
- `data-cart-id="container-id"` - ID for cart button container (optional, creates floating button if omitted)
|
|
371
|
-
- `data-show-cart-items` - Show items count badge on cart button (optional)
|
|
372
|
-
- `data-enable-debugging` - Enable debug logging in development (optional)
|
|
228
|
+
### Advanced Auto-Init Features
|
|
373
229
|
|
|
374
|
-
Add
|
|
230
|
+
#### Add Product via URL (Marketing Links)
|
|
231
|
+
|
|
232
|
+
Enable "add to cart" via URL parameters for email campaigns and ads:
|
|
375
233
|
|
|
376
234
|
```html
|
|
377
|
-
<
|
|
378
|
-
|
|
379
|
-
|
|
235
|
+
<script
|
|
236
|
+
data-liquid-commerce-elements
|
|
237
|
+
data-token="YOUR_API_KEY"
|
|
238
|
+
data-env="production"
|
|
239
|
+
data-product-param="lce_product"
|
|
240
|
+
data-product-fulfillment-type-param="lce_fulfillment"
|
|
241
|
+
src="https://assets-elements.liquidcommerce.us/all/elements.js"
|
|
242
|
+
></script>
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Now this URL auto-adds a product to cart:
|
|
246
|
+
```
|
|
247
|
+
https://yoursite.com/shop?lce_product=00619947000020&lce_fulfillment=shipping
|
|
380
248
|
```
|
|
381
249
|
|
|
382
|
-
|
|
250
|
+
**Use case:** Email campaigns, social media ads, QR codes
|
|
383
251
|
|
|
384
|
-
|
|
252
|
+
#### Apply Promo Code via URL (Campaign Tracking)
|
|
385
253
|
|
|
386
|
-
|
|
254
|
+
Auto-apply promo codes from URL parameters:
|
|
387
255
|
|
|
388
256
|
```html
|
|
389
257
|
<script
|
|
390
258
|
data-liquid-commerce-elements
|
|
391
259
|
data-token="YOUR_API_KEY"
|
|
392
260
|
data-env="production"
|
|
393
|
-
data-
|
|
394
|
-
data-product-1="00619947000020"
|
|
395
|
-
data-container-2="pdp-2"
|
|
396
|
-
data-product-2="00832889005513"
|
|
261
|
+
data-promo-code-param="lce_promo"
|
|
397
262
|
src="https://assets-elements.liquidcommerce.us/all/elements.js"
|
|
398
263
|
></script>
|
|
399
264
|
```
|
|
400
265
|
|
|
401
|
-
|
|
266
|
+
Now this URL auto-applies a promo code:
|
|
267
|
+
```
|
|
268
|
+
https://yoursite.com/shop?lce_promo=SUMMER20
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
**Use case:** Promotional campaigns, influencer codes, affiliate links
|
|
272
|
+
|
|
273
|
+
#### Promo Ticker (Rotating Promotions)
|
|
274
|
+
|
|
275
|
+
Display rotating promotional messages:
|
|
402
276
|
|
|
403
277
|
```html
|
|
404
|
-
<script
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
278
|
+
<script
|
|
279
|
+
data-liquid-commerce-elements
|
|
280
|
+
data-token="YOUR_API_KEY"
|
|
281
|
+
data-env="production"
|
|
282
|
+
data-promo-code="FREESHIP"
|
|
283
|
+
data-promo-text="Free Shipping Today Only!|Use code FREESHIP at checkout"
|
|
284
|
+
data-promo-separator="•"
|
|
285
|
+
data-promo-active-from="2025-01-01T00:00:00Z"
|
|
286
|
+
data-promo-active-until="2025-01-31T23:59:59Z"
|
|
287
|
+
src="https://assets-elements.liquidcommerce.us/all/elements.js"
|
|
288
|
+
></script>
|
|
410
289
|
```
|
|
411
290
|
|
|
412
|
-
|
|
291
|
+
**Use case:** Time-sensitive promotions, holiday sales, flash deals
|
|
292
|
+
|
|
293
|
+
#### Debug Mode (Development)
|
|
294
|
+
|
|
295
|
+
Enable debug logging during development:
|
|
413
296
|
|
|
414
297
|
```html
|
|
415
|
-
<
|
|
416
|
-
|
|
298
|
+
<script
|
|
299
|
+
data-liquid-commerce-elements
|
|
300
|
+
data-token="YOUR_API_KEY"
|
|
301
|
+
data-env="development"
|
|
302
|
+
data-debug-mode="console"
|
|
303
|
+
src="https://assets-elements.liquidcommerce.us/all/elements.js"
|
|
304
|
+
></script>
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
**Debug modes:**
|
|
308
|
+
- `console` - Logs to browser console
|
|
309
|
+
- `panel` - Shows visual debug panel + console logs
|
|
310
|
+
- Not set - No debugging (production default)
|
|
311
|
+
|
|
312
|
+
### Complete Auto-Init Reference
|
|
313
|
+
|
|
314
|
+
Here's every available data attribute:
|
|
315
|
+
|
|
316
|
+
```html
|
|
317
|
+
<script
|
|
318
|
+
data-liquid-commerce-elements
|
|
319
|
+
|
|
320
|
+
<!-- Required -->
|
|
321
|
+
data-token="YOUR_API_KEY"
|
|
322
|
+
|
|
323
|
+
<!-- Environment -->
|
|
324
|
+
data-env="production|staging|development|local"
|
|
325
|
+
|
|
326
|
+
<!-- Cart Button -->
|
|
327
|
+
data-cart-id="container-id"
|
|
328
|
+
data-show-cart-items
|
|
329
|
+
data-hide-cart-floating-button
|
|
330
|
+
|
|
331
|
+
<!-- Products (Method 1: Direct) -->
|
|
332
|
+
data-container-1="div-id"
|
|
333
|
+
data-product-1="identifier"
|
|
334
|
+
data-container-2="div-id"
|
|
335
|
+
data-product-2="identifier"
|
|
336
|
+
|
|
337
|
+
<!-- URL Parameters -->
|
|
338
|
+
data-product-param="lce_product"
|
|
339
|
+
data-product-fulfillment-type-param="lce_fulfillment"
|
|
340
|
+
data-promo-code-param="lce_promo"
|
|
341
|
+
|
|
342
|
+
<!-- Promo Ticker -->
|
|
343
|
+
data-promo-code="CODE"
|
|
344
|
+
data-promo-text="Message 1|Message 2"
|
|
345
|
+
data-promo-separator="•"
|
|
346
|
+
data-promo-active-from="2025-01-01T00:00:00Z"
|
|
347
|
+
data-promo-active-until="2025-12-31T23:59:59Z"
|
|
348
|
+
|
|
349
|
+
<!-- Debugging (dev only) -->
|
|
350
|
+
data-debug-mode="console|panel"
|
|
351
|
+
|
|
352
|
+
src="https://assets-elements.liquidcommerce.us/all/elements.js"
|
|
353
|
+
></script>
|
|
417
354
|
```
|
|
418
355
|
|
|
419
|
-
|
|
356
|
+
**📖 For complete auto-init options:** See [`docs/CONFIGURATION.md`](docs/CONFIGURATION.md) for all data attributes and configuration details.
|
|
420
357
|
|
|
421
|
-
|
|
358
|
+
---
|
|
359
|
+
|
|
360
|
+
## 🔧 Advanced Usage
|
|
361
|
+
|
|
362
|
+
Need more control? Initialize programmatically for full access to the SDK API.
|
|
363
|
+
|
|
364
|
+
### Installation
|
|
365
|
+
|
|
366
|
+
**CDN:**
|
|
367
|
+
```html
|
|
368
|
+
<script src="https://assets-elements.liquidcommerce.us/all/elements.js"></script>
|
|
369
|
+
|
|
370
|
+
<!-- Pin to specific version: -->
|
|
371
|
+
<script src="https://assets-elements.liquidcommerce.us/all/1.2.3/elements.js"></script>
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
**NPM:**
|
|
375
|
+
```bash
|
|
376
|
+
npm install @liquidcommerce/elements-sdk
|
|
377
|
+
# or
|
|
378
|
+
pnpm add @liquidcommerce/elements-sdk
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
### Programmatic Initialization
|
|
422
382
|
|
|
423
383
|
```html
|
|
424
384
|
<script src="https://assets-elements.liquidcommerce.us/all/elements.js"></script>
|
|
425
385
|
<script>
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
}
|
|
386
|
+
(async () => {
|
|
387
|
+
const client = await window.Elements('YOUR_API_KEY', {
|
|
388
|
+
env: 'production',
|
|
389
|
+
debugMode: 'none',
|
|
390
|
+
customTheme: { /* theming overrides */ },
|
|
391
|
+
proxy: { /* proxy config */ }
|
|
392
|
+
});
|
|
432
393
|
|
|
433
|
-
|
|
434
|
-
|
|
394
|
+
// Inject components
|
|
395
|
+
await client.injectProductElement([
|
|
396
|
+
{ containerId: 'pdp-1', identifier: '00619947000020' }
|
|
397
|
+
]);
|
|
398
|
+
|
|
399
|
+
// Create cart button
|
|
400
|
+
client.ui.cartButton('cart-container', true);
|
|
401
|
+
|
|
402
|
+
// Use actions API
|
|
403
|
+
await client.actions.cart.addProduct([{
|
|
404
|
+
identifier: '00619947000020',
|
|
405
|
+
fulfillmentType: 'shipping',
|
|
406
|
+
quantity: 1
|
|
407
|
+
}]);
|
|
408
|
+
})();
|
|
435
409
|
</script>
|
|
436
410
|
```
|
|
437
411
|
|
|
438
|
-
|
|
412
|
+
**NPM Import:**
|
|
413
|
+
```js
|
|
414
|
+
import { Elements } from '@liquidcommerce/elements-sdk';
|
|
415
|
+
|
|
416
|
+
const client = await Elements('YOUR_API_KEY', { env: 'production' });
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
---
|
|
420
|
+
|
|
421
|
+
## 🌐 Browser Support
|
|
422
|
+
|
|
423
|
+
⚠️ **Important**: This SDK is designed for browser environments only. It will not work in server-side rendering, Node.js, or other non-browser environments.
|
|
439
424
|
|
|
440
|
-
###
|
|
425
|
+
### Supported Browsers (2018+)
|
|
441
426
|
|
|
442
|
-
|
|
427
|
+
| Browser | Minimum Version | Released |
|
|
428
|
+
|---------|----------------|----------|
|
|
429
|
+
| Chrome | 66+ | April 2018 |
|
|
430
|
+
| Firefox | 60+ | May 2018 |
|
|
431
|
+
| Safari | 12+ | September 2018 |
|
|
432
|
+
| Edge | 79+ (Chromium) | January 2020 |
|
|
433
|
+
| Samsung Internet | 7.2+ | June 2018 |
|
|
443
434
|
|
|
444
|
-
|
|
435
|
+
📖 See [`docs/BROWSER_SUPPORT.md`](docs/BROWSER_SUPPORT.md) for detailed compatibility.
|
|
445
436
|
|
|
446
|
-
|
|
437
|
+
## ⚙️ Configuration
|
|
447
438
|
|
|
448
|
-
|
|
439
|
+
### Basic Configuration
|
|
449
440
|
|
|
450
441
|
```js
|
|
451
|
-
await
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
442
|
+
const client = await Elements('YOUR_API_KEY', {
|
|
443
|
+
env: 'production', // Environment
|
|
444
|
+
debugMode: 'none', // Debug mode
|
|
445
|
+
customTheme: { }, // Theme overrides
|
|
446
|
+
proxy: { }, // Proxy configuration
|
|
447
|
+
promoTicker: [ ] // Promotional messages
|
|
448
|
+
});
|
|
455
449
|
```
|
|
456
450
|
|
|
457
|
-
|
|
451
|
+
### Environment Options
|
|
458
452
|
|
|
459
|
-
|
|
453
|
+
```js
|
|
454
|
+
env: 'production' // Live environment (default)
|
|
455
|
+
env: 'staging' // Pre-production testing
|
|
456
|
+
env: 'development' // Development with extra logging
|
|
457
|
+
env: 'local' // Local development
|
|
458
|
+
```
|
|
460
459
|
|
|
461
|
-
|
|
460
|
+
### Debug Modes
|
|
462
461
|
|
|
463
462
|
```js
|
|
464
|
-
|
|
463
|
+
debugMode: 'none' // No debugging (production default)
|
|
464
|
+
debugMode: 'console' // Console logs only
|
|
465
|
+
debugMode: 'panel' // Visual debug panel + console logs
|
|
465
466
|
```
|
|
466
467
|
|
|
467
|
-
|
|
468
|
+
**Note:** Debug mode is automatically disabled in production environment for security.
|
|
468
469
|
|
|
469
|
-
|
|
470
|
+
### Custom Theme
|
|
470
471
|
|
|
471
|
-
|
|
472
|
+
Override default styles and layouts:
|
|
472
473
|
|
|
473
474
|
```js
|
|
474
|
-
|
|
475
|
+
customTheme: {
|
|
476
|
+
global: {
|
|
477
|
+
theme: {
|
|
478
|
+
primaryColor: '#007bff',
|
|
479
|
+
accentColor: '#6c757d',
|
|
480
|
+
successColor: '#28a745',
|
|
481
|
+
errorColor: '#dc3545',
|
|
482
|
+
buttonCornerRadius: '8px',
|
|
483
|
+
cardCornerRadius: '12px',
|
|
484
|
+
headingFont: {
|
|
485
|
+
name: 'Inter',
|
|
486
|
+
weights: [600, 700]
|
|
487
|
+
},
|
|
488
|
+
paragraphFont: {
|
|
489
|
+
name: 'Inter',
|
|
490
|
+
weights: [400, 500]
|
|
491
|
+
}
|
|
492
|
+
},
|
|
493
|
+
layout: {
|
|
494
|
+
allowPromoCodes: true,
|
|
495
|
+
inputFieldStyle: 'outlined'
|
|
496
|
+
}
|
|
497
|
+
},
|
|
498
|
+
product: {
|
|
499
|
+
layout: {
|
|
500
|
+
showDescription: true,
|
|
501
|
+
addToCartButtonText: 'Add to Cart',
|
|
502
|
+
fulfillmentDisplay: 'carousel'
|
|
503
|
+
}
|
|
504
|
+
},
|
|
505
|
+
cart: {
|
|
506
|
+
layout: {
|
|
507
|
+
showQuantityCounter: true,
|
|
508
|
+
drawerHeaderText: 'Your Cart'
|
|
509
|
+
}
|
|
510
|
+
},
|
|
511
|
+
checkout: {
|
|
512
|
+
layout: {
|
|
513
|
+
allowGiftCards: true,
|
|
514
|
+
emailOptIn: { show: true, checked: false, text: 'Email me with news' },
|
|
515
|
+
smsOptIn: { show: true, checked: false, text: 'Text me with updates' }
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
}
|
|
475
519
|
```
|
|
476
520
|
|
|
477
|
-
|
|
521
|
+
**📖 For complete theming options:** See [`docs/THEMING.md`](docs/THEMING.md)
|
|
478
522
|
|
|
479
|
-
|
|
523
|
+
### Proxy Configuration
|
|
480
524
|
|
|
481
|
-
|
|
525
|
+
Route API requests through your server to avoid ad blockers:
|
|
482
526
|
|
|
483
527
|
```js
|
|
484
|
-
|
|
528
|
+
proxy: {
|
|
529
|
+
baseUrl: 'https://yourdomain.com/api/proxy',
|
|
530
|
+
headers: {
|
|
531
|
+
'X-Custom-Auth': 'your-token'
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
See [`docs/PROXY.md`](docs/PROXY.md) for implementation guide.
|
|
537
|
+
|
|
538
|
+
### Promo Ticker
|
|
539
|
+
|
|
540
|
+
Display rotating promotional messages:
|
|
541
|
+
|
|
542
|
+
```js
|
|
543
|
+
promoTicker: [
|
|
544
|
+
{
|
|
545
|
+
promoCode: 'FREESHIP',
|
|
546
|
+
text: ['Free Shipping Today!', 'Use code FREESHIP'],
|
|
547
|
+
separator: '•',
|
|
548
|
+
activeFrom: '2025-01-01T00:00:00Z',
|
|
549
|
+
activeUntil: '2025-12-31T23:59:59Z'
|
|
550
|
+
}
|
|
551
|
+
]
|
|
485
552
|
```
|
|
486
553
|
|
|
487
|
-
|
|
554
|
+
**📖 For all configuration options:** See [`docs/CONFIGURATION.md`](docs/CONFIGURATION.md) for complete reference with TypeScript types.
|
|
555
|
+
|
|
556
|
+
---
|
|
557
|
+
|
|
558
|
+
## 📖 SDK Methods & API
|
|
559
|
+
|
|
560
|
+
### Component Injection
|
|
488
561
|
|
|
489
|
-
|
|
562
|
+
Inject SDK components into your page containers.
|
|
563
|
+
|
|
564
|
+
#### Products
|
|
565
|
+
|
|
566
|
+
```js
|
|
567
|
+
await client.injectProductElement([
|
|
568
|
+
{ containerId: 'pdp-1', identifier: '00619947000020' },
|
|
569
|
+
{ containerId: 'pdp-2', identifier: '00832889005513' }
|
|
570
|
+
]);
|
|
571
|
+
```
|
|
490
572
|
|
|
491
|
-
|
|
573
|
+
**Identifier types:** UPC, product ID, or Salsify grouping ID
|
|
492
574
|
|
|
493
|
-
|
|
575
|
+
#### Cart
|
|
494
576
|
|
|
495
577
|
```js
|
|
496
|
-
client.
|
|
578
|
+
await client.injectCartElement('cart-container');
|
|
579
|
+
```
|
|
580
|
+
|
|
581
|
+
**Use case:** Dedicated cart page
|
|
582
|
+
|
|
583
|
+
#### Checkout
|
|
497
584
|
|
|
498
|
-
|
|
499
|
-
client.
|
|
585
|
+
```js
|
|
586
|
+
await client.injectCheckoutElement('checkout-container');
|
|
500
587
|
```
|
|
501
588
|
|
|
502
|
-
|
|
589
|
+
**Use case:** Dedicated checkout page
|
|
503
590
|
|
|
504
|
-
|
|
591
|
+
#### Address
|
|
505
592
|
|
|
506
593
|
```js
|
|
507
|
-
client.
|
|
594
|
+
await client.injectAddressElement('address-container');
|
|
595
|
+
```
|
|
508
596
|
|
|
509
|
-
|
|
510
|
-
|
|
597
|
+
**Use case:** Shipping address collection page
|
|
598
|
+
|
|
599
|
+
### UI Helpers
|
|
600
|
+
|
|
601
|
+
Create standalone UI elements that integrate with the SDK.
|
|
602
|
+
|
|
603
|
+
#### Cart Button (in container)
|
|
604
|
+
|
|
605
|
+
```js
|
|
606
|
+
client.ui.cartButton('header-cart', true);
|
|
511
607
|
```
|
|
512
608
|
|
|
513
|
-
|
|
609
|
+
**Parameters:**
|
|
610
|
+
- `containerId` - Where to place the button
|
|
611
|
+
- `showItemsCount` - Show item count badge (optional)
|
|
514
612
|
|
|
515
|
-
|
|
613
|
+
**Use case:** Header navigation, sidebar
|
|
516
614
|
|
|
517
|
-
|
|
615
|
+
#### Floating Cart Button
|
|
518
616
|
|
|
519
617
|
```js
|
|
520
|
-
client.ui.
|
|
618
|
+
client.ui.floatingCartButton(true);
|
|
521
619
|
```
|
|
522
620
|
|
|
523
|
-
|
|
621
|
+
**Parameters:**
|
|
622
|
+
- `showItemsCount` - Show item count badge (optional)
|
|
623
|
+
|
|
624
|
+
**Use case:** Always-visible cart access (bottom-right corner)
|
|
524
625
|
|
|
525
|
-
|
|
626
|
+
#### Live Cart Data Display
|
|
627
|
+
|
|
628
|
+
Bind elements to auto-update with cart data:
|
|
526
629
|
|
|
527
630
|
```js
|
|
528
|
-
|
|
631
|
+
// Show live subtotal
|
|
632
|
+
client.ui.cartSubtotal('cart-total-display');
|
|
633
|
+
|
|
634
|
+
// Show live item count
|
|
635
|
+
client.ui.cartItemsCount('cart-badge');
|
|
636
|
+
```
|
|
637
|
+
|
|
638
|
+
**Example:**
|
|
639
|
+
```html
|
|
640
|
+
<nav>
|
|
641
|
+
<span>Cart: $<span id="cart-total-display">0.00</span></span>
|
|
642
|
+
<span>(<span id="cart-badge">0</span> items)</span>
|
|
643
|
+
</nav>
|
|
529
644
|
```
|
|
530
645
|
|
|
531
646
|
### Builder Methods (Development Mode)
|
|
@@ -568,7 +683,8 @@ const actions = window.elements.actions;
|
|
|
568
683
|
```js
|
|
569
684
|
// Get product details
|
|
570
685
|
const product = actions.product.getDetails('product-123');
|
|
571
|
-
console.log(product.
|
|
686
|
+
console.log(product.name, product.brand, product.region, product.variety);
|
|
687
|
+
console.log(product.priceInfo, product.description, product.tastingNotes);
|
|
572
688
|
```
|
|
573
689
|
|
|
574
690
|
### Address Actions
|
|
@@ -669,7 +785,7 @@ await actions.cart.removePromoCode();
|
|
|
669
785
|
|
|
670
786
|
// Get cart details
|
|
671
787
|
const cart = actions.cart.getDetails();
|
|
672
|
-
console.log(cart.total, cart.
|
|
788
|
+
console.log(cart.itemCount, cart.amounts.total, cart.amounts.giftCardTotal);
|
|
673
789
|
|
|
674
790
|
// Reset cart
|
|
675
791
|
await actions.cart.resetCart();
|
|
@@ -741,12 +857,10 @@ window.addEventListener('lce:actions.checkout_gift_card_failed', function(event)
|
|
|
741
857
|
|
|
742
858
|
// Get checkout details (safe, non-sensitive data only)
|
|
743
859
|
const checkout = actions.checkout.getDetails();
|
|
744
|
-
console.log(
|
|
745
|
-
console.log(
|
|
746
|
-
console.log(
|
|
747
|
-
console.log(
|
|
748
|
-
console.log('Has promo code:', checkout.hasPromoCode);
|
|
749
|
-
console.log('Has gift cards:', checkout.hasGiftCards);
|
|
860
|
+
console.log(checkout.itemCount, checkout.amounts.total, checkout.isGift);
|
|
861
|
+
console.log(checkout.hasAgeVerify, checkout.hasPromoCode, checkout.hasGiftCards);
|
|
862
|
+
console.log(checkout.acceptedAccountCreation, checkout.billingSameAsShipping);
|
|
863
|
+
console.log(checkout.marketingPreferences);
|
|
750
864
|
|
|
751
865
|
// Configure checkout options
|
|
752
866
|
await actions.checkout.toggleBillingSameAsShipping(true);
|
|
@@ -762,13 +876,14 @@ The SDK emits real-time events for all user interactions. Listen to these events
|
|
|
762
876
|
```js
|
|
763
877
|
// Listen for specific events
|
|
764
878
|
window.addEventListener('lce:actions.product_add_to_cart', function(event) {
|
|
765
|
-
const
|
|
766
|
-
console.log('Added to cart:',
|
|
879
|
+
const data = event.detail.data;
|
|
880
|
+
console.log('Added to cart:', data.identifier);
|
|
767
881
|
|
|
768
882
|
// Your custom logic here
|
|
769
883
|
analytics.track('Product Added', {
|
|
770
|
-
|
|
771
|
-
|
|
884
|
+
identifier: data.identifier,
|
|
885
|
+
quantity: data.quantity,
|
|
886
|
+
upc: data.upc
|
|
772
887
|
});
|
|
773
888
|
});
|
|
774
889
|
|
|
@@ -785,7 +900,7 @@ window.elements.onAllActions((data, metadata) => {
|
|
|
785
900
|
### Available Events
|
|
786
901
|
|
|
787
902
|
#### Product Events
|
|
788
|
-
- `lce:actions.product_loaded` - Product component loaded
|
|
903
|
+
- `lce:actions.product_loaded` - Product component loaded with comprehensive product details (region, country, abv, proof, age, variety, vintage, descriptions, tasting notes)
|
|
789
904
|
- `lce:actions.product_add_to_cart` - Item added to cart
|
|
790
905
|
- `lce:actions.product_quantity_increase` - Quantity increased
|
|
791
906
|
- `lce:actions.product_quantity_decrease` - Quantity decreased
|
|
@@ -793,6 +908,7 @@ window.elements.onAllActions((data, metadata) => {
|
|
|
793
908
|
- `lce:actions.product_fulfillment_type_changed` - Delivery method changed
|
|
794
909
|
|
|
795
910
|
#### Cart Events
|
|
911
|
+
- `lce:actions.cart_loaded` - Cart data loaded with complete cart information (itemCount, all amounts including giftCardTotal, detailed item data)
|
|
796
912
|
- `lce:actions.cart_opened` - Cart displayed
|
|
797
913
|
- `lce:actions.cart_closed` - Cart hidden
|
|
798
914
|
- `lce:actions.cart_updated` - Cart contents changed
|
|
@@ -801,6 +917,7 @@ window.elements.onAllActions((data, metadata) => {
|
|
|
801
917
|
- `lce:actions.cart_reset` - Cart cleared
|
|
802
918
|
|
|
803
919
|
#### Checkout Events
|
|
920
|
+
- `lce:actions.checkout_loaded` - Checkout data loaded with comprehensive details (acceptedAccountCreation, hasSubstitutionPolicy, billingSameAsShipping, marketing preferences, detailed items)
|
|
804
921
|
- `lce:actions.checkout_opened` - Checkout started
|
|
805
922
|
- `lce:actions.checkout_closed` - Checkout abandoned
|
|
806
923
|
- `lce:actions.checkout_submit_started` - Order submission began
|
|
@@ -813,361 +930,1299 @@ window.elements.onAllActions((data, metadata) => {
|
|
|
813
930
|
- `lce:actions.address_updated` - Address information changed
|
|
814
931
|
- `lce:actions.address_cleared` - Address removed
|
|
815
932
|
|
|
816
|
-
See [`docs/EVENTS.md`](docs/EVENTS.md) for complete event reference with implementation examples.
|
|
817
|
-
|
|
818
|
-
## ⚙️ Configuration
|
|
819
|
-
|
|
820
|
-
Configure the SDK when initializing:
|
|
821
|
-
|
|
822
|
-
```js
|
|
823
|
-
const client = await Elements('YOUR_API_KEY', {
|
|
824
|
-
env: 'production', // 'local' | 'development' | 'staging' | 'production'
|
|
825
|
-
enableDebugging: false, // Enable console logging (development only)
|
|
826
|
-
isBuilder: false, // Enable builder methods (development only)
|
|
827
|
-
customTheme: { /* theme overrides */ },
|
|
828
|
-
proxy: { /* proxy configuration */ }
|
|
829
|
-
});
|
|
830
|
-
```
|
|
831
|
-
|
|
832
|
-
### Environment Options
|
|
833
|
-
|
|
834
|
-
- **`production`**: Live environment for customer-facing sites
|
|
835
|
-
- **`staging`**: Pre-production testing environment
|
|
836
|
-
- **`development`**: Development environment with additional debugging
|
|
837
|
-
- **`local`**: Local development environment
|
|
838
|
-
|
|
839
|
-
### Auto-init Data Attributes
|
|
840
|
-
|
|
841
|
-
When using auto-initialization, configure via data attributes:
|
|
842
|
-
|
|
843
|
-
- `data-liquid-commerce-elements`: Required flag to enable auto-init
|
|
844
|
-
- `data-token`: Your API key (required)
|
|
845
|
-
- `data-env`: Environment (defaults to production)
|
|
846
|
-
- `data-cart-id`: Container ID for cart button
|
|
847
|
-
- `data-enable-debugging`: Enable debugging mode
|
|
848
|
-
- `data-container-X` / `data-product-X`: Product mapping pairs
|
|
933
|
+
See [`docs/EVENTS.md`](docs/EVENTS.md) for complete event reference with all available fields and implementation examples.
|
|
849
934
|
|
|
850
935
|
## 🎨 Themes & Customization
|
|
851
936
|
|
|
852
|
-
|
|
937
|
+
The SDK provides a theming system that lets you match components to your brand.
|
|
938
|
+
|
|
939
|
+
### Global Theming
|
|
853
940
|
|
|
854
941
|
```js
|
|
855
942
|
const client = await Elements('YOUR_API_KEY', {
|
|
856
|
-
env: 'production',
|
|
857
943
|
customTheme: {
|
|
858
944
|
global: {
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
945
|
+
theme: {
|
|
946
|
+
primaryColor: '#007bff',
|
|
947
|
+
accentColor: '#6c757d',
|
|
948
|
+
successColor: '#28a745',
|
|
949
|
+
errorColor: '#dc3545',
|
|
950
|
+
warningColor: '#ffc107',
|
|
951
|
+
defaultTextColor: '#212529',
|
|
952
|
+
selectedTextColor: '#ffffff',
|
|
953
|
+
drawerBackgroundColor: '#ffffff',
|
|
954
|
+
buttonCornerRadius: '8px',
|
|
955
|
+
cardCornerRadius: '12px',
|
|
956
|
+
headingFont: {
|
|
957
|
+
name: 'Inter',
|
|
958
|
+
weights: [600, 700]
|
|
959
|
+
},
|
|
960
|
+
paragraphFont: {
|
|
961
|
+
name: 'Inter',
|
|
962
|
+
weights: [400, 500]
|
|
963
|
+
}
|
|
872
964
|
},
|
|
873
|
-
colors: {
|
|
874
|
-
price: '#28a745',
|
|
875
|
-
sale: '#dc3545'
|
|
876
|
-
}
|
|
877
|
-
},
|
|
878
|
-
cart: {
|
|
879
|
-
layout: {
|
|
880
|
-
showRetailerLogos: true,
|
|
881
|
-
compactMode: false
|
|
882
|
-
}
|
|
883
|
-
},
|
|
884
|
-
checkout: {
|
|
885
965
|
layout: {
|
|
886
|
-
|
|
887
|
-
|
|
966
|
+
enablePersonalization: true,
|
|
967
|
+
personalizationText: 'Customize your product',
|
|
968
|
+
personalizationCardStyle: 'outlined',
|
|
969
|
+
allowPromoCodes: true,
|
|
970
|
+
inputFieldStyle: 'outlined',
|
|
971
|
+
poweredByMode: 'light'
|
|
888
972
|
}
|
|
889
973
|
}
|
|
890
974
|
}
|
|
891
975
|
});
|
|
892
976
|
```
|
|
893
977
|
|
|
894
|
-
|
|
978
|
+
### Component-Specific Theming
|
|
979
|
+
|
|
980
|
+
#### Product Component
|
|
895
981
|
|
|
896
982
|
```js
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
983
|
+
customTheme: {
|
|
984
|
+
product: {
|
|
985
|
+
theme: {
|
|
986
|
+
backgroundColor: '#ffffff'
|
|
987
|
+
},
|
|
988
|
+
layout: {
|
|
989
|
+
showImages: true,
|
|
990
|
+
showTitle: true,
|
|
991
|
+
showDescription: true,
|
|
992
|
+
showQuantityCounter: true,
|
|
993
|
+
quantityCounterStyle: 'outlined',
|
|
994
|
+
fulfillmentDisplay: 'carousel',
|
|
995
|
+
enableShippingFulfillment: true,
|
|
996
|
+
enableOnDemandFulfillment: true,
|
|
997
|
+
addToCartButtonText: 'Add to Cart',
|
|
998
|
+
buyNowButtonText: 'Buy Now'
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
```
|
|
1003
|
+
|
|
1004
|
+
#### Cart Component
|
|
1005
|
+
|
|
1006
|
+
```js
|
|
1007
|
+
customTheme: {
|
|
1008
|
+
cart: {
|
|
1009
|
+
theme: {
|
|
1010
|
+
backgroundColor: '#ffffff'
|
|
1011
|
+
},
|
|
1012
|
+
layout: {
|
|
1013
|
+
showQuantityCounter: true,
|
|
1014
|
+
quantityCounterStyle: 'outlined',
|
|
1015
|
+
drawerHeaderText: 'Your Cart',
|
|
1016
|
+
goToCheckoutButtonText: 'Checkout'
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
```
|
|
1021
|
+
|
|
1022
|
+
#### Checkout Component
|
|
1023
|
+
|
|
1024
|
+
```js
|
|
1025
|
+
customTheme: {
|
|
1026
|
+
checkout: {
|
|
1027
|
+
theme: {
|
|
1028
|
+
backgroundColor: '#ffffff',
|
|
1029
|
+
checkoutCompleted: {
|
|
1030
|
+
customLogo: 'https://yourdomain.com/logo.png',
|
|
1031
|
+
customText: 'Thank you for your order!'
|
|
1032
|
+
}
|
|
1033
|
+
},
|
|
1034
|
+
layout: {
|
|
1035
|
+
emailOptIn: {
|
|
1036
|
+
show: true,
|
|
1037
|
+
checked: false,
|
|
1038
|
+
text: 'Email me with news'
|
|
1039
|
+
},
|
|
1040
|
+
smsOptIn: {
|
|
1041
|
+
show: true,
|
|
1042
|
+
checked: false,
|
|
1043
|
+
text: 'Text me updates'
|
|
1044
|
+
},
|
|
1045
|
+
allowGiftCards: true,
|
|
1046
|
+
drawerHeaderText: 'Checkout',
|
|
1047
|
+
placeOrderButtonText: 'Place Order'
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
```
|
|
1052
|
+
|
|
1053
|
+
#### Address Component
|
|
1054
|
+
|
|
1055
|
+
```js
|
|
1056
|
+
customTheme: {
|
|
1057
|
+
address: {
|
|
1058
|
+
theme: {
|
|
1059
|
+
backgroundColor: '#ffffff'
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
```
|
|
1064
|
+
|
|
1065
|
+
### Dynamic Theme Updates (Builder Mode)
|
|
1066
|
+
|
|
1067
|
+
In development with `isBuilder: true`, update themes in real-time:
|
|
1068
|
+
|
|
1069
|
+
```js
|
|
1070
|
+
const client = await Elements('YOUR_API_KEY', {
|
|
1071
|
+
env: 'development',
|
|
1072
|
+
isBuilder: true
|
|
900
1073
|
});
|
|
901
1074
|
|
|
1075
|
+
// Update global theme
|
|
1076
|
+
await client.builder.updateComponentGlobalConfigs({
|
|
1077
|
+
theme: { primaryColor: '#ff6b6b' }
|
|
1078
|
+
});
|
|
1079
|
+
|
|
1080
|
+
// Update component-specific themes
|
|
902
1081
|
await client.builder.updateProductComponent({
|
|
903
|
-
layout: {
|
|
1082
|
+
layout: { addToCartButtonText: 'Add to Bag' }
|
|
1083
|
+
});
|
|
1084
|
+
|
|
1085
|
+
client.builder.updateCartComponent({
|
|
1086
|
+
layout: { drawerHeaderText: 'Shopping Bag' }
|
|
1087
|
+
});
|
|
1088
|
+
|
|
1089
|
+
client.builder.updateCheckoutComponent({
|
|
1090
|
+
layout: { placeOrderButtonText: 'Complete Purchase' }
|
|
1091
|
+
});
|
|
1092
|
+
|
|
1093
|
+
client.builder.updateAddressComponent({
|
|
1094
|
+
theme: { backgroundColor: '#f8f9fa' }
|
|
904
1095
|
});
|
|
905
1096
|
```
|
|
906
1097
|
|
|
907
|
-
|
|
1098
|
+
**📖 For complete theming documentation:** See [`docs/THEMING.md`](docs/THEMING.md)
|
|
908
1099
|
|
|
909
|
-
|
|
1100
|
+
---
|
|
1101
|
+
|
|
1102
|
+
## 🎁 Features Deep Dive
|
|
1103
|
+
|
|
1104
|
+
### Product Personalization (Engraving)
|
|
1105
|
+
|
|
1106
|
+
The SDK provides a comprehensive personalization/engraving feature for products that support it. The personalization experience varies based on context:
|
|
1107
|
+
|
|
1108
|
+
#### Product View
|
|
1109
|
+
When browsing products, customers can add personalization through an enhanced form that includes:
|
|
1110
|
+
- Product information with pricing
|
|
1111
|
+
- Fulfillment/retailer selection (with pricing comparison)
|
|
1112
|
+
- Multi-line engraving inputs with character limits
|
|
1113
|
+
- Real-time price updates as customers select different retailers
|
|
1114
|
+
- Add-to-cart with personalization in one step
|
|
1115
|
+
|
|
1116
|
+
```js
|
|
1117
|
+
// Personalization appears automatically for engravable products
|
|
1118
|
+
// Customers can add engraving text and select which retailer to fulfill from
|
|
1119
|
+
|
|
1120
|
+
// Listen for when personalization is added via add-to-cart
|
|
1121
|
+
window.addEventListener('lce:actions.product_add_to_cart', (event) => {
|
|
1122
|
+
const { hasEngraving, engravingLines } = event.detail.data;
|
|
1123
|
+
if (hasEngraving) {
|
|
1124
|
+
console.log('Customer personalized:', engravingLines);
|
|
1125
|
+
}
|
|
1126
|
+
});
|
|
1127
|
+
```
|
|
1128
|
+
|
|
1129
|
+
#### Cart View
|
|
1130
|
+
In the cart, personalized items display:
|
|
1131
|
+
- Personalization text lines
|
|
1132
|
+
- Engraving fee (per item and total for quantity)
|
|
1133
|
+
- **Edit** button to modify the personalization
|
|
1134
|
+
- **Remove** button to remove personalization
|
|
1135
|
+
|
|
1136
|
+
```js
|
|
1137
|
+
// Customers can edit or remove engraving from cart items
|
|
1138
|
+
window.addEventListener('lce:actions.cart_item_engraving_updated', (event) => {
|
|
1139
|
+
const { identifier, engravingLines } = event.detail.data;
|
|
1140
|
+
console.log('Cart item engraving updated:', engravingLines);
|
|
1141
|
+
});
|
|
1142
|
+
```
|
|
1143
|
+
|
|
1144
|
+
#### Checkout View
|
|
1145
|
+
During checkout, personalized items show:
|
|
1146
|
+
- Personalization text lines (read-only)
|
|
1147
|
+
- Engraving fee included in pricing
|
|
1148
|
+
- **Remove** button only (editing not allowed in checkout)
|
|
1149
|
+
|
|
1150
|
+
**Design Decision:** Editing personalization during checkout is intentionally disabled to prevent order processing complications. Customers must return to the cart to make changes.
|
|
1151
|
+
|
|
1152
|
+
#### Theming & Configuration
|
|
1153
|
+
|
|
1154
|
+
Control personalization display through global configuration:
|
|
1155
|
+
|
|
1156
|
+
```js
|
|
1157
|
+
customTheme: {
|
|
1158
|
+
global: {
|
|
1159
|
+
layout: {
|
|
1160
|
+
enablePersonalization: true,
|
|
1161
|
+
personalizationText: 'Personalize your product',
|
|
1162
|
+
personalizationCardStyle: 'outlined' // or 'filled'
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
```
|
|
1167
|
+
|
|
1168
|
+
#### Key Features
|
|
1169
|
+
- **Smart pricing:** Automatically includes engraving fees in product price
|
|
1170
|
+
- **Retailer selection:** Compare prices from different retailers during personalization
|
|
1171
|
+
- **Character limits:** Enforces maximum characters per line
|
|
1172
|
+
- **Uppercase conversion:** Engraving text is automatically converted to uppercase
|
|
1173
|
+
- **Multi-line support:** Products can support 1 or more engraving lines
|
|
1174
|
+
- **Fee transparency:** Shows per-item and total fees (e.g., "$5.00 ($2.50 ea)")
|
|
1175
|
+
|
|
1176
|
+
**Note:** Personalization is automatically enabled for products that support it. The SDK handles all UI, validation, and state management.
|
|
1177
|
+
|
|
1178
|
+
### Gift Options
|
|
1179
|
+
|
|
1180
|
+
Allow orders to be marked as gifts with custom messages:
|
|
1181
|
+
|
|
1182
|
+
```js
|
|
1183
|
+
// Enable via theme
|
|
1184
|
+
customTheme: {
|
|
1185
|
+
checkout: {
|
|
1186
|
+
layout: {
|
|
1187
|
+
allowGiftOptions: true
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
// Toggle gift mode programmatically
|
|
1193
|
+
await client.actions.checkout.toggleIsGift(true);
|
|
1194
|
+
|
|
1195
|
+
// Set gift message
|
|
1196
|
+
await client.actions.checkout.updateGiftInfo({
|
|
1197
|
+
recipientName: 'John Doe',
|
|
1198
|
+
message: 'Happy Birthday!'
|
|
1199
|
+
});
|
|
1200
|
+
|
|
1201
|
+
// Listen for gift toggles
|
|
1202
|
+
window.addEventListener('lce:actions.checkout_is_gift_toggled', (event) => {
|
|
1203
|
+
const { isGift } = event.detail.data;
|
|
1204
|
+
console.log('Order is gift:', isGift);
|
|
1205
|
+
});
|
|
1206
|
+
```
|
|
1207
|
+
|
|
1208
|
+
### Tips (On-Demand Delivery)
|
|
1209
|
+
|
|
1210
|
+
Allow customers to tip delivery drivers:
|
|
1211
|
+
|
|
1212
|
+
```js
|
|
1213
|
+
// Tips are automatically enabled for onDemand fulfillment types
|
|
1214
|
+
|
|
1215
|
+
// Listen for tip updates
|
|
1216
|
+
window.addEventListener('lce:actions.checkout_tip_updated', (event) => {
|
|
1217
|
+
const { tipAmount, total } = event.detail.data;
|
|
1218
|
+
console.log(`Customer tipped $${tipAmount}`);
|
|
1219
|
+
});
|
|
1220
|
+
```
|
|
1221
|
+
|
|
1222
|
+
Tips are calculated as a percentage or fixed amount and added to the order total.
|
|
1223
|
+
|
|
1224
|
+
### Gift Cards
|
|
1225
|
+
|
|
1226
|
+
Accept gift card payments at checkout:
|
|
1227
|
+
|
|
1228
|
+
```js
|
|
1229
|
+
// Enable via theme
|
|
1230
|
+
customTheme: {
|
|
1231
|
+
checkout: {
|
|
1232
|
+
layout: {
|
|
1233
|
+
allowGiftCards: true
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
// Apply gift card programmatically
|
|
1239
|
+
await client.actions.checkout.applyGiftCard('GIFT-1234-5678-9012');
|
|
1240
|
+
|
|
1241
|
+
// Remove gift card
|
|
1242
|
+
await client.actions.checkout.removeGiftCard('GIFT-1234-5678-9012');
|
|
1243
|
+
|
|
1244
|
+
// Listen for gift card events
|
|
1245
|
+
window.addEventListener('lce:actions.checkout_gift_card_applied', (event) => {
|
|
1246
|
+
const { code, appliedAmount, remainingBalance } = event.detail.data;
|
|
1247
|
+
console.log(`Applied $${appliedAmount}, Remaining: $${remainingBalance}`);
|
|
1248
|
+
});
|
|
1249
|
+
|
|
1250
|
+
window.addEventListener('lce:actions.checkout_gift_card_failed', (event) => {
|
|
1251
|
+
const { code, error } = event.detail.data;
|
|
1252
|
+
console.log('Gift card failed:', error);
|
|
1253
|
+
});
|
|
1254
|
+
```
|
|
1255
|
+
|
|
1256
|
+
### Promo Codes
|
|
1257
|
+
|
|
1258
|
+
Apply promotional discount codes:
|
|
910
1259
|
|
|
911
1260
|
```js
|
|
1261
|
+
// Apply to cart
|
|
1262
|
+
await client.actions.cart.applyPromoCode('SUMMER20');
|
|
1263
|
+
|
|
1264
|
+
// Apply to checkout
|
|
1265
|
+
await client.actions.checkout.applyPromoCode('SAVE10');
|
|
1266
|
+
|
|
1267
|
+
// Remove promo code
|
|
1268
|
+
await client.actions.cart.removePromoCode();
|
|
1269
|
+
|
|
1270
|
+
// Listen for promo events
|
|
1271
|
+
window.addEventListener('lce:actions.cart_promo_code_applied', (event) => {
|
|
1272
|
+
const { code, discountAmount, newTotal } = event.detail.data;
|
|
1273
|
+
console.log(`${code} saved $${discountAmount}! New total: $${newTotal}`);
|
|
1274
|
+
});
|
|
1275
|
+
|
|
1276
|
+
window.addEventListener('lce:actions.cart_promo_code_failed', (event) => {
|
|
1277
|
+
const { code, error } = event.detail.data;
|
|
1278
|
+
console.log('Promo failed:', error.message);
|
|
1279
|
+
});
|
|
1280
|
+
```
|
|
1281
|
+
|
|
1282
|
+
### Promo Ticker
|
|
1283
|
+
|
|
1284
|
+
Display rotating promotional messages at the top of your site:
|
|
1285
|
+
|
|
1286
|
+
```js
|
|
1287
|
+
// Via initialization config
|
|
912
1288
|
const client = await Elements('YOUR_API_KEY', {
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
1289
|
+
promoTicker: [
|
|
1290
|
+
{
|
|
1291
|
+
promoCode: 'FREESHIP',
|
|
1292
|
+
text: ['Free Shipping Today!', 'Use code FREESHIP'],
|
|
1293
|
+
separator: '•',
|
|
1294
|
+
activeFrom: '2025-01-01T00:00:00Z',
|
|
1295
|
+
activeUntil: '2025-12-31T23:59:59Z'
|
|
1296
|
+
},
|
|
1297
|
+
{
|
|
1298
|
+
promoCode: 'SAVE20',
|
|
1299
|
+
text: ['20% Off Sitewide', 'Limited Time Only'],
|
|
1300
|
+
separator: '|',
|
|
1301
|
+
activeFrom: '2025-06-01T00:00:00Z',
|
|
1302
|
+
activeUntil: '2025-06-30T23:59:59Z'
|
|
1303
|
+
}
|
|
1304
|
+
]
|
|
1305
|
+
});
|
|
1306
|
+
|
|
1307
|
+
// Via auto-init
|
|
1308
|
+
<script
|
|
1309
|
+
data-liquid-commerce-elements
|
|
1310
|
+
data-token="YOUR_API_KEY"
|
|
1311
|
+
data-promo-code="FREESHIP"
|
|
1312
|
+
data-promo-text="Free Shipping Today!|Use code FREESHIP"
|
|
1313
|
+
data-promo-separator="•"
|
|
1314
|
+
data-promo-active-from="2025-01-01T00:00:00Z"
|
|
1315
|
+
data-promo-active-until="2025-12-31T23:59:59Z"
|
|
1316
|
+
src="https://assets-elements.liquidcommerce.us/all/elements.js"
|
|
1317
|
+
></script>
|
|
1318
|
+
```
|
|
1319
|
+
|
|
1320
|
+
The ticker automatically rotates messages and only shows active promotions.
|
|
1321
|
+
|
|
1322
|
+
### Marketing Preferences
|
|
1323
|
+
|
|
1324
|
+
Allow customers to opt-in to email and SMS marketing:
|
|
1325
|
+
|
|
1326
|
+
```js
|
|
1327
|
+
// Set defaults via theme
|
|
1328
|
+
customTheme: {
|
|
1329
|
+
checkout: {
|
|
1330
|
+
layout: {
|
|
1331
|
+
emailOptIn: { checked: false, visible: true },
|
|
1332
|
+
smsOptIn: { checked: false, visible: true }
|
|
918
1333
|
}
|
|
919
1334
|
}
|
|
1335
|
+
}
|
|
1336
|
+
|
|
1337
|
+
// Update preferences programmatically
|
|
1338
|
+
await client.actions.checkout.toggleMarketingPreferences('canEmail', true);
|
|
1339
|
+
await client.actions.checkout.toggleMarketingPreferences('canSms', true);
|
|
1340
|
+
|
|
1341
|
+
// Listen for preference changes
|
|
1342
|
+
window.addEventListener('lce:actions.checkout_marketing_preferences_toggled', (event) => {
|
|
1343
|
+
const { field, value } = event.detail.data;
|
|
1344
|
+
console.log(`Customer ${value ? 'opted-in' : 'opted-out'} of ${field}`);
|
|
920
1345
|
});
|
|
921
1346
|
```
|
|
922
1347
|
|
|
923
|
-
|
|
1348
|
+
### Purchase Minimum Alerts
|
|
924
1349
|
|
|
925
|
-
|
|
1350
|
+
Automatically displays alerts when a retailer has minimum purchase requirements. No configuration needed - the SDK handles this automatically based on retailer rules.
|
|
926
1351
|
|
|
927
|
-
|
|
1352
|
+
### Age Verification
|
|
928
1353
|
|
|
929
|
-
-
|
|
930
|
-
- [`docs/EVENTS.md`](docs/EVENTS.md) - Events guide with implementation examples
|
|
931
|
-
- [`docs/BROWSER_SUPPORT.md`](docs/BROWSER_SUPPORT.md) - Detailed browser compatibility
|
|
932
|
-
- [`docs/PROXY.md`](docs/PROXY.md) - Proxy configuration for ad blocker avoidance
|
|
1354
|
+
For age-restricted products (alcohol, tobacco, etc.), the SDK automatically displays age verification prompts during checkout. This is handled based on product metadata and cannot be disabled for restricted items.
|
|
933
1355
|
|
|
934
|
-
|
|
1356
|
+
### Pre-Sale Countdown
|
|
1357
|
+
|
|
1358
|
+
For pre-sale or upcoming products, the SDK automatically displays a countdown timer until the product becomes available. Customers can add pre-sale items to cart, and the SDK handles the special fulfillment flow.
|
|
1359
|
+
|
|
1360
|
+
```js
|
|
1361
|
+
// Listen for when product is added to cart
|
|
1362
|
+
window.addEventListener('lce:actions.product_add_to_cart', (event) => {
|
|
1363
|
+
const { productId } = event.detail.data;
|
|
1364
|
+
console.log(`Product ${productId} added to cart`);
|
|
1365
|
+
});
|
|
1366
|
+
```
|
|
1367
|
+
|
|
1368
|
+
---
|
|
935
1369
|
|
|
936
|
-
|
|
1370
|
+
## 🔧 Core Capabilities
|
|
937
1371
|
|
|
938
|
-
|
|
939
|
-
- Branch: `beta`
|
|
940
|
-
- Base URL: `https://assets-elements.liquidcommerce.us/all/beta/`
|
|
941
|
-
- Purpose: Testing and pre-release features
|
|
1372
|
+
The SDK includes several built-in services that work behind the scenes to provide a robust, production-ready experience.
|
|
942
1373
|
|
|
943
|
-
###
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
1374
|
+
### State Management
|
|
1375
|
+
|
|
1376
|
+
The SDK uses a centralized store for all state management. Access state data via actions:
|
|
1377
|
+
|
|
1378
|
+
```js
|
|
1379
|
+
// Get current cart state
|
|
1380
|
+
const cart = await client.actions.cart.getDetails();
|
|
1381
|
+
console.log(cart.itemCount, cart.amounts.total, cart.amounts.giftCardTotal);
|
|
947
1382
|
|
|
948
|
-
|
|
1383
|
+
// Get current checkout state
|
|
1384
|
+
const checkout = await client.actions.checkout.getDetails();
|
|
1385
|
+
console.log(checkout.amounts.total, checkout.isGift, checkout.acceptedAccountCreation);
|
|
1386
|
+
console.log(checkout.billingSameAsShipping, checkout.marketingPreferences);
|
|
949
1387
|
|
|
1388
|
+
// Get current address
|
|
1389
|
+
const address = await client.actions.address.getDetails();
|
|
1390
|
+
console.log(address.formattedAddress, address.coordinates);
|
|
1391
|
+
|
|
1392
|
+
// Get product details
|
|
1393
|
+
const product = await client.actions.product.getDetails('00619947000020');
|
|
1394
|
+
console.log(product.name, product.region, product.variety, product.vintage);
|
|
1395
|
+
console.log(product.description, product.tastingNotes);
|
|
950
1396
|
```
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
1397
|
+
|
|
1398
|
+
**State is persistent:** Cart and address data persist across page reloads using localStorage.
|
|
1399
|
+
|
|
1400
|
+
### Event System (PubSub)
|
|
1401
|
+
|
|
1402
|
+
All SDK interactions emit events through a centralized event system:
|
|
1403
|
+
|
|
1404
|
+
```js
|
|
1405
|
+
// Subscribe to specific event
|
|
1406
|
+
window.addEventListener('lce:actions.cart_updated', (event) => {
|
|
1407
|
+
const { previous, current } = event.detail.data;
|
|
1408
|
+
console.log('Cart changed from', previous.amounts.total, 'to', current.amounts.total);
|
|
1409
|
+
});
|
|
1410
|
+
|
|
1411
|
+
// Subscribe to all action events
|
|
1412
|
+
if (window.elements) {
|
|
1413
|
+
window.elements.onAllActions((data, metadata) => {
|
|
1414
|
+
console.log('Action:', metadata.eventName, data);
|
|
1415
|
+
});
|
|
1416
|
+
}
|
|
1417
|
+
|
|
1418
|
+
// Subscribe to all form events
|
|
1419
|
+
if (window.elements) {
|
|
1420
|
+
window.elements.onAllForms((data, metadata) => {
|
|
1421
|
+
console.log('Form:', metadata.eventName, data);
|
|
1422
|
+
});
|
|
1423
|
+
}
|
|
1424
|
+
```
|
|
1425
|
+
|
|
1426
|
+
**Event format:**
|
|
1427
|
+
```js
|
|
1428
|
+
{
|
|
1429
|
+
detail: {
|
|
1430
|
+
data: { /* event-specific payload */ },
|
|
1431
|
+
metadata: {
|
|
1432
|
+
eventName: 'lce:actions.cart_updated',
|
|
1433
|
+
timestamp: 1699564800000,
|
|
1434
|
+
source: 'sdk'
|
|
1435
|
+
}
|
|
1436
|
+
}
|
|
1437
|
+
}
|
|
1438
|
+
```
|
|
1439
|
+
|
|
1440
|
+
### Telemetry & Analytics
|
|
1441
|
+
|
|
1442
|
+
The SDK automatically tracks user interactions and performance metrics:
|
|
1443
|
+
|
|
1444
|
+
- **User interactions:** Add to cart, checkout started, checkout completed
|
|
1445
|
+
- **Performance metrics:** Component load times, API response times
|
|
1446
|
+
- **Error tracking:** Failed API calls, validation errors
|
|
1447
|
+
|
|
1448
|
+
**Note:** The SDK includes automatic Google Tag Manager (GTM) integration that tracks e-commerce events. GTM configuration is managed through your LiquidCommerce dashboard, not the client initialization.
|
|
1449
|
+
|
|
1450
|
+
**Custom Analytics:**
|
|
1451
|
+
|
|
1452
|
+
```js
|
|
1453
|
+
// Listen to events for custom analytics tracking
|
|
1454
|
+
window.addEventListener('lce:actions.product_add_to_cart', (event) => {
|
|
1455
|
+
const { productId, price, quantity } = event.detail.data;
|
|
1456
|
+
|
|
1457
|
+
// Track with your analytics provider
|
|
1458
|
+
gtag('event', 'add_to_cart', {
|
|
1459
|
+
currency: 'USD',
|
|
1460
|
+
value: price * quantity,
|
|
1461
|
+
items: [{ item_id: productId, quantity }]
|
|
1462
|
+
});
|
|
1463
|
+
|
|
1464
|
+
// Or Segment
|
|
1465
|
+
analytics.track('Product Added', {
|
|
1466
|
+
product_id: productId,
|
|
1467
|
+
price,
|
|
1468
|
+
quantity
|
|
1469
|
+
});
|
|
1470
|
+
});
|
|
960
1471
|
```
|
|
961
1472
|
|
|
962
|
-
|
|
1473
|
+
### Circuit Breaker
|
|
963
1474
|
|
|
964
|
-
The SDK includes
|
|
1475
|
+
The SDK includes a circuit breaker pattern to prevent cascading failures:
|
|
965
1476
|
|
|
966
|
-
|
|
1477
|
+
```js
|
|
1478
|
+
// Automatically handles API failures
|
|
1479
|
+
// - After 5 consecutive failures, circuit opens
|
|
1480
|
+
// - Requests fail fast without hitting the API
|
|
1481
|
+
// - After 30 seconds, circuit half-opens
|
|
1482
|
+
// - Next successful request closes the circuit
|
|
1483
|
+
```
|
|
1484
|
+
|
|
1485
|
+
**Circuit states:**
|
|
1486
|
+
- **Closed:** Normal operation, all requests go through
|
|
1487
|
+
- **Open:** API is failing, requests fail fast
|
|
1488
|
+
- **Half-Open:** Testing if API recovered, limited requests allowed
|
|
1489
|
+
|
|
1490
|
+
This protects your site from slowdowns when the API is experiencing issues.
|
|
1491
|
+
|
|
1492
|
+
### Fingerprinting
|
|
1493
|
+
|
|
1494
|
+
The SDK generates a unique device fingerprint for fraud prevention and analytics:
|
|
1495
|
+
|
|
1496
|
+
```js
|
|
1497
|
+
// Automatically tracked:
|
|
1498
|
+
// - Browser fingerprint
|
|
1499
|
+
// - Device characteristics
|
|
1500
|
+
// - Session information
|
|
1501
|
+
|
|
1502
|
+
// Used for:
|
|
1503
|
+
// - Fraud detection
|
|
1504
|
+
// - Cart persistence across devices
|
|
1505
|
+
// - Personalization
|
|
1506
|
+
```
|
|
1507
|
+
|
|
1508
|
+
Fingerprinting is handled automatically and requires no configuration.
|
|
1509
|
+
|
|
1510
|
+
### Authentication
|
|
1511
|
+
|
|
1512
|
+
The SDK handles authentication automatically using your API key:
|
|
1513
|
+
|
|
1514
|
+
```js
|
|
1515
|
+
const client = await Elements('YOUR_API_KEY', {
|
|
1516
|
+
env: 'production'
|
|
1517
|
+
});
|
|
1518
|
+
|
|
1519
|
+
// All API requests include:
|
|
1520
|
+
// - API key authentication
|
|
1521
|
+
// - CORS headers
|
|
1522
|
+
// - Request signing (when required)
|
|
1523
|
+
```
|
|
1524
|
+
|
|
1525
|
+
**Token refresh:** The SDK automatically handles token expiration and refresh.
|
|
1526
|
+
|
|
1527
|
+
### Logger
|
|
967
1528
|
|
|
968
|
-
|
|
1529
|
+
Built-in logging system with configurable levels:
|
|
1530
|
+
|
|
1531
|
+
```js
|
|
1532
|
+
const client = await Elements('YOUR_API_KEY', {
|
|
1533
|
+
debugMode: 'console' // 'none' | 'console' | 'panel'
|
|
1534
|
+
});
|
|
1535
|
+
|
|
1536
|
+
// Debug mode options:
|
|
1537
|
+
// - 'none': No logging (production default)
|
|
1538
|
+
// - 'console': Logs to browser console
|
|
1539
|
+
// - 'panel': Shows visual debug panel + console logs
|
|
1540
|
+
```
|
|
1541
|
+
|
|
1542
|
+
**Console debug output:**
|
|
1543
|
+
```
|
|
1544
|
+
[LCE SDK] Product loaded: product-123
|
|
1545
|
+
[LCE SDK] Cart updated: 3 items, $45.99
|
|
1546
|
+
[LCE SDK] Checkout started
|
|
1547
|
+
[LCE SDK] API call: POST /cart/add (152ms)
|
|
1548
|
+
```
|
|
1549
|
+
|
|
1550
|
+
**Debug panel:**
|
|
1551
|
+
- Real-time event stream
|
|
1552
|
+
- API call inspector
|
|
1553
|
+
- State viewer
|
|
1554
|
+
- Performance metrics
|
|
1555
|
+
|
|
1556
|
+
### Command Pattern
|
|
1557
|
+
|
|
1558
|
+
The SDK uses a command pattern for all operations:
|
|
1559
|
+
|
|
1560
|
+
```js
|
|
1561
|
+
// Commands are:
|
|
1562
|
+
// - Queued for execution
|
|
1563
|
+
// - Retried on failure
|
|
1564
|
+
// - Logged for debugging
|
|
1565
|
+
// - Cancelable
|
|
1566
|
+
|
|
1567
|
+
// Example: Adding to cart
|
|
1568
|
+
// 1. Command created: AddToCartCommand
|
|
1569
|
+
// 2. Command queued
|
|
1570
|
+
// 3. Command executed
|
|
1571
|
+
// 4. Success event emitted
|
|
1572
|
+
// 5. UI updated
|
|
1573
|
+
|
|
1574
|
+
// This ensures:
|
|
1575
|
+
// - Consistent error handling
|
|
1576
|
+
// - Automatic retries
|
|
1577
|
+
// - Full audit trail
|
|
1578
|
+
```
|
|
1579
|
+
|
|
1580
|
+
### Component Factory
|
|
1581
|
+
|
|
1582
|
+
Components are created on-demand using a factory pattern:
|
|
1583
|
+
|
|
1584
|
+
```js
|
|
1585
|
+
// When you call:
|
|
1586
|
+
await client.injectProductElement([
|
|
1587
|
+
{ containerId: 'pdp-1', identifier: 'product-123' }
|
|
1588
|
+
]);
|
|
1589
|
+
|
|
1590
|
+
// The SDK:
|
|
1591
|
+
// 1. Creates a ProductComponent instance
|
|
1592
|
+
// 2. Registers it with the factory
|
|
1593
|
+
// 3. Injects it into the DOM
|
|
1594
|
+
// 4. Attaches event listeners
|
|
1595
|
+
// 5. Loads product data
|
|
1596
|
+
// 6. Renders the component
|
|
1597
|
+
|
|
1598
|
+
// Components are:
|
|
1599
|
+
// - Lazily loaded
|
|
1600
|
+
// - Automatically cleaned up
|
|
1601
|
+
// - Reusable across pages
|
|
1602
|
+
```
|
|
1603
|
+
|
|
1604
|
+
### Singleton Manager
|
|
1605
|
+
|
|
1606
|
+
Core services are managed as singletons:
|
|
1607
|
+
|
|
1608
|
+
```js
|
|
1609
|
+
// These services are initialized once and reused:
|
|
1610
|
+
// - ApiClient
|
|
1611
|
+
// - Store
|
|
1612
|
+
// - PubSub
|
|
1613
|
+
// - Logger
|
|
1614
|
+
// - Telemetry
|
|
1615
|
+
// - CircuitBreaker
|
|
1616
|
+
// - Fingerprint
|
|
1617
|
+
// - Auth
|
|
1618
|
+
|
|
1619
|
+
// This ensures:
|
|
1620
|
+
// - Consistent state
|
|
1621
|
+
// - Efficient memory usage
|
|
1622
|
+
// - No duplicate API calls
|
|
1623
|
+
```
|
|
1624
|
+
|
|
1625
|
+
---
|
|
1626
|
+
|
|
1627
|
+
## 🏗️ Integration Patterns
|
|
1628
|
+
|
|
1629
|
+
### React Integration
|
|
1630
|
+
|
|
1631
|
+
```jsx
|
|
1632
|
+
import { useEffect, useState } from 'react';
|
|
1633
|
+
import { Elements } from '@liquidcommerce/elements-sdk';
|
|
1634
|
+
|
|
1635
|
+
function ProductPage({ productId }) {
|
|
1636
|
+
const [client, setClient] = useState(null);
|
|
1637
|
+
|
|
1638
|
+
useEffect(() => {
|
|
1639
|
+
async function initSDK() {
|
|
1640
|
+
const elementsClient = await Elements(process.env.REACT_APP_LCE_API_KEY, {
|
|
1641
|
+
env: 'production'
|
|
1642
|
+
});
|
|
1643
|
+
setClient(elementsClient);
|
|
1644
|
+
|
|
1645
|
+
// Inject product
|
|
1646
|
+
await elementsClient.injectProductElement([
|
|
1647
|
+
{ containerId: 'product-container', identifier: productId }
|
|
1648
|
+
]);
|
|
1649
|
+
|
|
1650
|
+
// Create cart button
|
|
1651
|
+
elementsClient.ui.cartButton('cart-button', true);
|
|
1652
|
+
}
|
|
1653
|
+
|
|
1654
|
+
initSDK();
|
|
1655
|
+
|
|
1656
|
+
// Cleanup
|
|
1657
|
+
return () => {
|
|
1658
|
+
// SDK handles cleanup automatically
|
|
1659
|
+
};
|
|
1660
|
+
}, [productId]);
|
|
1661
|
+
|
|
1662
|
+
return (
|
|
1663
|
+
<div>
|
|
1664
|
+
<div id="cart-button"></div>
|
|
1665
|
+
<div id="product-container"></div>
|
|
1666
|
+
</div>
|
|
1667
|
+
);
|
|
1668
|
+
}
|
|
1669
|
+
```
|
|
1670
|
+
|
|
1671
|
+
### Vue Integration
|
|
1672
|
+
|
|
1673
|
+
```vue
|
|
1674
|
+
<template>
|
|
1675
|
+
<div>
|
|
1676
|
+
<div ref="cartButton"></div>
|
|
1677
|
+
<div ref="productContainer"></div>
|
|
1678
|
+
</div>
|
|
1679
|
+
</template>
|
|
1680
|
+
|
|
1681
|
+
<script>
|
|
1682
|
+
import { Elements } from '@liquidcommerce/elements-sdk';
|
|
1683
|
+
|
|
1684
|
+
export default {
|
|
1685
|
+
name: 'ProductPage',
|
|
1686
|
+
props: ['productId'],
|
|
1687
|
+
async mounted() {
|
|
1688
|
+
this.client = await Elements(process.env.VUE_APP_LCE_API_KEY, {
|
|
1689
|
+
env: 'production'
|
|
1690
|
+
});
|
|
1691
|
+
|
|
1692
|
+
await this.client.injectProductElement([
|
|
1693
|
+
{ containerId: this.$refs.productContainer.id, identifier: this.productId }
|
|
1694
|
+
]);
|
|
1695
|
+
|
|
1696
|
+
this.client.ui.cartButton(this.$refs.cartButton.id, true);
|
|
1697
|
+
}
|
|
1698
|
+
}
|
|
1699
|
+
</script>
|
|
1700
|
+
```
|
|
1701
|
+
|
|
1702
|
+
### Next.js Integration
|
|
1703
|
+
|
|
1704
|
+
```tsx
|
|
1705
|
+
'use client';
|
|
1706
|
+
|
|
1707
|
+
import { useEffect } from 'react';
|
|
1708
|
+
|
|
1709
|
+
export default function ProductPage({ productId }: { productId: string }) {
|
|
1710
|
+
useEffect(() => {
|
|
1711
|
+
// Load SDK script
|
|
1712
|
+
const script = document.createElement('script');
|
|
1713
|
+
script.src = 'https://assets-elements.liquidcommerce.us/all/elements.js';
|
|
1714
|
+
script.async = true;
|
|
1715
|
+
script.onload = async () => {
|
|
1716
|
+
const client = await (window as any).Elements(process.env.NEXT_PUBLIC_LCE_API_KEY, {
|
|
1717
|
+
env: 'production'
|
|
1718
|
+
});
|
|
1719
|
+
|
|
1720
|
+
await client.injectProductElement([
|
|
1721
|
+
{ containerId: 'product-container', identifier: productId }
|
|
1722
|
+
]);
|
|
1723
|
+
|
|
1724
|
+
client.ui.floatingCartButton(true);
|
|
1725
|
+
};
|
|
1726
|
+
document.body.appendChild(script);
|
|
1727
|
+
|
|
1728
|
+
return () => {
|
|
1729
|
+
document.body.removeChild(script);
|
|
1730
|
+
};
|
|
1731
|
+
}, [productId]);
|
|
1732
|
+
|
|
1733
|
+
return <div id="product-container"></div>;
|
|
1734
|
+
}
|
|
1735
|
+
```
|
|
1736
|
+
|
|
1737
|
+
### WordPress Integration
|
|
969
1738
|
|
|
970
1739
|
```html
|
|
971
|
-
<!--
|
|
1740
|
+
<!-- In your theme's header.php or functions.php -->
|
|
972
1741
|
<script
|
|
973
1742
|
data-liquid-commerce-elements
|
|
974
|
-
data-token="
|
|
975
|
-
data-env="
|
|
976
|
-
|
|
977
|
-
src="../umd/elements.js"
|
|
1743
|
+
data-token="<?php echo get_option('lce_api_key'); ?>"
|
|
1744
|
+
data-env="production"
|
|
1745
|
+
src="https://assets-elements.liquidcommerce.us/all/elements.js"
|
|
978
1746
|
></script>
|
|
1747
|
+
|
|
1748
|
+
<!-- In your product template -->
|
|
1749
|
+
<div data-lce-product="<?php echo get_post_meta(get_the_ID(), 'product_upc', true); ?>"></div>
|
|
979
1750
|
```
|
|
980
1751
|
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
1752
|
+
### Shopify Integration
|
|
1753
|
+
|
|
1754
|
+
```html
|
|
1755
|
+
<!-- In theme.liquid -->
|
|
1756
|
+
<script
|
|
1757
|
+
data-liquid-commerce-elements
|
|
1758
|
+
data-token="{{ settings.lce_api_key }}"
|
|
1759
|
+
data-env="production"
|
|
1760
|
+
src="https://assets-elements.liquidcommerce.us/all/elements.js"
|
|
1761
|
+
></script>
|
|
986
1762
|
|
|
987
|
-
|
|
1763
|
+
<!-- In product template -->
|
|
1764
|
+
<div data-lce-product="{{ product.barcode }}"></div>
|
|
1765
|
+
```
|
|
988
1766
|
|
|
989
|
-
###
|
|
1767
|
+
### Multi-Page Applications
|
|
990
1768
|
|
|
991
|
-
|
|
1769
|
+
For SPAs and multi-page apps, initialize once and reuse:
|
|
992
1770
|
|
|
993
|
-
```
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
1771
|
+
```js
|
|
1772
|
+
// app.js (initialize once)
|
|
1773
|
+
let elementsClient = null;
|
|
1774
|
+
|
|
1775
|
+
async function getElementsClient() {
|
|
1776
|
+
if (!elementsClient) {
|
|
1777
|
+
elementsClient = await Elements('YOUR_API_KEY', {
|
|
1778
|
+
env: 'production'
|
|
1779
|
+
});
|
|
1780
|
+
}
|
|
1781
|
+
return elementsClient;
|
|
1782
|
+
}
|
|
999
1783
|
|
|
1000
|
-
//
|
|
1001
|
-
client
|
|
1784
|
+
// product-page.js
|
|
1785
|
+
const client = await getElementsClient();
|
|
1002
1786
|
await client.injectProductElement([
|
|
1003
|
-
{ containerId:
|
|
1787
|
+
{ containerId: 'pdp-1', identifier: productId }
|
|
1004
1788
|
]);
|
|
1005
|
-
|
|
1789
|
+
|
|
1790
|
+
// cart-page.js
|
|
1791
|
+
const client = await getElementsClient();
|
|
1792
|
+
await client.injectCartElement('cart-container');
|
|
1006
1793
|
```
|
|
1007
1794
|
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
- Dynamic theme updates
|
|
1795
|
+
---
|
|
1796
|
+
|
|
1797
|
+
## 🚨 Error Handling
|
|
1798
|
+
|
|
1799
|
+
### Initialization Errors
|
|
1014
1800
|
|
|
1015
|
-
|
|
1801
|
+
```js
|
|
1802
|
+
try {
|
|
1803
|
+
const client = await Elements('YOUR_API_KEY', {
|
|
1804
|
+
env: 'production'
|
|
1805
|
+
});
|
|
1806
|
+
} catch (error) {
|
|
1807
|
+
if (error.message.includes('Invalid API key')) {
|
|
1808
|
+
console.error('Authentication failed');
|
|
1809
|
+
} else if (error.message.includes('Network')) {
|
|
1810
|
+
console.error('Network error - check connectivity');
|
|
1811
|
+
} else {
|
|
1812
|
+
console.error('SDK initialization failed:', error);
|
|
1813
|
+
}
|
|
1814
|
+
}
|
|
1815
|
+
```
|
|
1016
1816
|
|
|
1017
|
-
###
|
|
1817
|
+
### Action Errors
|
|
1018
1818
|
|
|
1019
|
-
|
|
1020
|
-
2. **Open demo files** in your browser
|
|
1021
|
-
3. **Update API keys** with your own credentials
|
|
1022
|
-
4. **Modify environment** settings as needed (`development`, `staging`, `production`)
|
|
1819
|
+
All actions emit failure events with detailed error information:
|
|
1023
1820
|
|
|
1024
|
-
|
|
1821
|
+
```js
|
|
1822
|
+
// Product loaded successfully
|
|
1823
|
+
window.addEventListener('lce:actions.product_loaded', (event) => {
|
|
1824
|
+
const { identifier, productData } = event.detail.data;
|
|
1825
|
+
console.log(`Product ${identifier} loaded successfully`);
|
|
1826
|
+
});
|
|
1025
1827
|
|
|
1026
|
-
|
|
1828
|
+
// Cart action failure
|
|
1829
|
+
window.addEventListener('lce:actions.cart_product_add_failed', (event) => {
|
|
1830
|
+
const { identifiers, error } = event.detail.data;
|
|
1831
|
+
console.error('Failed to add products:', error);
|
|
1832
|
+
|
|
1833
|
+
// Show user-friendly message
|
|
1834
|
+
showNotification('Could not add to cart. Please try again.', 'error');
|
|
1835
|
+
});
|
|
1027
1836
|
|
|
1028
|
-
|
|
1837
|
+
// Checkout failure
|
|
1838
|
+
window.addEventListener('lce:actions.checkout_submit_failed', (event) => {
|
|
1839
|
+
const { error, reason } = event.detail.data;
|
|
1840
|
+
console.error('Checkout failed:', reason);
|
|
1841
|
+
|
|
1842
|
+
// Handle specific errors
|
|
1843
|
+
if (reason.includes('payment')) {
|
|
1844
|
+
showNotification('Payment declined. Please check your card details.', 'error');
|
|
1845
|
+
} else if (reason.includes('inventory')) {
|
|
1846
|
+
showNotification('Some items are no longer available.', 'warning');
|
|
1847
|
+
} else {
|
|
1848
|
+
showNotification('Checkout failed. Please try again.', 'error');
|
|
1849
|
+
}
|
|
1850
|
+
});
|
|
1029
1851
|
|
|
1030
|
-
|
|
1852
|
+
// Address validation failure
|
|
1853
|
+
window.addEventListener('lce:actions.address_failed', (event) => {
|
|
1854
|
+
const { error } = event.detail.data;
|
|
1855
|
+
console.error('Address validation failed:', error);
|
|
1856
|
+
showNotification('Please enter a valid address.', 'error');
|
|
1857
|
+
});
|
|
1031
1858
|
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1859
|
+
// Promo code failure
|
|
1860
|
+
window.addEventListener('lce:actions.cart_promo_code_failed', (event) => {
|
|
1861
|
+
const { code, error } = event.detail.data;
|
|
1862
|
+
console.error(`Promo code ${code} failed:`, error);
|
|
1863
|
+
|
|
1864
|
+
if (error.includes('expired')) {
|
|
1865
|
+
showNotification('This promo code has expired.', 'warning');
|
|
1866
|
+
} else if (error.includes('invalid')) {
|
|
1867
|
+
showNotification('Invalid promo code.', 'error');
|
|
1868
|
+
} else if (error.includes('minimum')) {
|
|
1869
|
+
showNotification('Cart minimum not met for this promo.', 'warning');
|
|
1870
|
+
}
|
|
1871
|
+
});
|
|
1035
1872
|
```
|
|
1036
|
-
- Creates optimized ESM and UMD bundles for production
|
|
1037
|
-
- Generates TypeScript declarations
|
|
1038
|
-
- Enables minification and compression
|
|
1039
|
-
- Removes console logs and debugging code
|
|
1040
|
-
- **Output:** `dist/index.esm.js` (ESM) + `umd/elements.js` (UMD)
|
|
1041
1873
|
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1874
|
+
### Network Error Recovery
|
|
1875
|
+
|
|
1876
|
+
```js
|
|
1877
|
+
let retryCount = 0;
|
|
1878
|
+
const maxRetries = 3;
|
|
1879
|
+
|
|
1880
|
+
async function addProductWithRetry(productParams) {
|
|
1881
|
+
try {
|
|
1882
|
+
await client.actions.cart.addProduct(productParams);
|
|
1883
|
+
} catch (error) {
|
|
1884
|
+
if (retryCount < maxRetries && error.message.includes('Network')) {
|
|
1885
|
+
retryCount++;
|
|
1886
|
+
console.log(`Retrying... Attempt ${retryCount}/${maxRetries}`);
|
|
1887
|
+
setTimeout(() => addProductWithRetry(productParams), 1000 * retryCount);
|
|
1888
|
+
} else {
|
|
1889
|
+
console.error('Failed after retries:', error);
|
|
1890
|
+
showNotification('Network error. Please check your connection.', 'error');
|
|
1891
|
+
}
|
|
1892
|
+
}
|
|
1893
|
+
}
|
|
1045
1894
|
```
|
|
1046
|
-
- Creates unminified bundles with source maps
|
|
1047
|
-
- Preserves console logs and debugging code
|
|
1048
|
-
- Faster build times for development
|
|
1049
|
-
- **Output:** Same as build but with debugging enabled
|
|
1050
1895
|
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1896
|
+
### Global Error Handler
|
|
1897
|
+
|
|
1898
|
+
```js
|
|
1899
|
+
// Listen to all failed events
|
|
1900
|
+
window.addEventListener('lce:actions.cart_failed', handleError);
|
|
1901
|
+
window.addEventListener('lce:actions.checkout_failed', handleError);
|
|
1902
|
+
window.addEventListener('lce:actions.address_failed', handleError);
|
|
1903
|
+
window.addEventListener('lce:actions.cart_product_add_failed', handleError);
|
|
1904
|
+
|
|
1905
|
+
function handleError(event) {
|
|
1906
|
+
const { error, context } = event.detail.data;
|
|
1907
|
+
|
|
1908
|
+
// Log to error tracking service
|
|
1909
|
+
if (window.Sentry) {
|
|
1910
|
+
Sentry.captureException(error, {
|
|
1911
|
+
tags: { sdk: 'liquid-commerce' },
|
|
1912
|
+
extra: context
|
|
1913
|
+
});
|
|
1914
|
+
}
|
|
1915
|
+
|
|
1916
|
+
// Show user notification
|
|
1917
|
+
showNotification('Something went wrong. Please try again.', 'error');
|
|
1918
|
+
}
|
|
1054
1919
|
```
|
|
1055
|
-
- Same as `build:dev` but watches for file changes
|
|
1056
|
-
- Automatically rebuilds on source code changes
|
|
1057
|
-
- **Best for:** Active development
|
|
1058
1920
|
|
|
1059
|
-
|
|
1921
|
+
---
|
|
1060
1922
|
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1923
|
+
## ⚡ Performance & Best Practices
|
|
1924
|
+
|
|
1925
|
+
### Lazy Loading Components
|
|
1926
|
+
|
|
1927
|
+
Only inject components when needed:
|
|
1928
|
+
|
|
1929
|
+
```js
|
|
1930
|
+
// ❌ Don't inject all components upfront
|
|
1931
|
+
await client.injectProductElement([/* 50 products */]);
|
|
1932
|
+
await client.injectCartElement('cart');
|
|
1933
|
+
await client.injectCheckoutElement('checkout');
|
|
1934
|
+
|
|
1935
|
+
// ✅ Inject components as user navigates
|
|
1936
|
+
// On product page:
|
|
1937
|
+
await client.injectProductElement([{ containerId: 'pdp', identifier: productId }]);
|
|
1938
|
+
|
|
1939
|
+
// On cart page (when user clicks cart):
|
|
1940
|
+
await client.injectCartElement('cart');
|
|
1941
|
+
|
|
1942
|
+
// On checkout (when user proceeds):
|
|
1943
|
+
await client.injectCheckoutElement('checkout');
|
|
1064
1944
|
```
|
|
1065
|
-
- Uses Biome to lint TypeScript/JavaScript files
|
|
1066
|
-
- Automatically fixes fixable issues
|
|
1067
|
-
- Enforces code style and catches common errors
|
|
1068
1945
|
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1946
|
+
### Reuse Client Instance
|
|
1947
|
+
|
|
1948
|
+
Initialize once, use everywhere:
|
|
1949
|
+
|
|
1950
|
+
```js
|
|
1951
|
+
// ❌ Don't create multiple clients
|
|
1952
|
+
// page1.js
|
|
1953
|
+
const client1 = await Elements('KEY', { env: 'production' });
|
|
1954
|
+
// page2.js
|
|
1955
|
+
const client2 = await Elements('KEY', { env: 'production' });
|
|
1956
|
+
|
|
1957
|
+
// ✅ Create once, reuse
|
|
1958
|
+
// app.js
|
|
1959
|
+
window.lceClient = await Elements('KEY', { env: 'production' });
|
|
1960
|
+
|
|
1961
|
+
// page1.js
|
|
1962
|
+
const client = window.lceClient;
|
|
1963
|
+
await client.injectProductElement([...]);
|
|
1964
|
+
|
|
1965
|
+
// page2.js
|
|
1966
|
+
const client = window.lceClient;
|
|
1967
|
+
await client.injectCartElement('cart');
|
|
1072
1968
|
```
|
|
1073
|
-
- Uses Biome to format all source files
|
|
1074
|
-
- Ensures consistent code formatting
|
|
1075
|
-
- Applies formatting rules defined in `biome.json`
|
|
1076
1969
|
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1970
|
+
### Batch Product Injections
|
|
1971
|
+
|
|
1972
|
+
Group product injections together:
|
|
1973
|
+
|
|
1974
|
+
```js
|
|
1975
|
+
// ❌ Don't inject products one by one
|
|
1976
|
+
await client.injectProductElement([{ containerId: 'p1', identifier: 'id1' }]);
|
|
1977
|
+
await client.injectProductElement([{ containerId: 'p2', identifier: 'id2' }]);
|
|
1978
|
+
await client.injectProductElement([{ containerId: 'p3', identifier: 'id3' }]);
|
|
1979
|
+
|
|
1980
|
+
// ✅ Inject all products at once
|
|
1981
|
+
await client.injectProductElement([
|
|
1982
|
+
{ containerId: 'p1', identifier: 'id1' },
|
|
1983
|
+
{ containerId: 'p2', identifier: 'id2' },
|
|
1984
|
+
{ containerId: 'p3', identifier: 'id3' }
|
|
1985
|
+
]);
|
|
1080
1986
|
```
|
|
1081
|
-
- Runs both linting and formatting in one command
|
|
1082
|
-
- Auto-fixes issues and formats code
|
|
1083
|
-
- **Recommended before commits**
|
|
1084
1987
|
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1988
|
+
### Optimize Event Listeners
|
|
1989
|
+
|
|
1990
|
+
Use event delegation instead of multiple listeners:
|
|
1991
|
+
|
|
1992
|
+
```js
|
|
1993
|
+
// ❌ Don't listen to every event
|
|
1994
|
+
window.addEventListener('lce:actions.product_loaded', handler);
|
|
1995
|
+
window.addEventListener('lce:actions.product_add_to_cart', handler);
|
|
1996
|
+
window.addEventListener('lce:actions.cart_updated', handler);
|
|
1997
|
+
// ... 20 more listeners
|
|
1998
|
+
|
|
1999
|
+
// ✅ Use consolidated listeners
|
|
2000
|
+
window.elements.onAllActions((data, metadata) => {
|
|
2001
|
+
switch (metadata.eventName) {
|
|
2002
|
+
case 'lce:actions.product_loaded':
|
|
2003
|
+
handleProductLoad(data);
|
|
2004
|
+
break;
|
|
2005
|
+
case 'lce:actions.product_add_to_cart':
|
|
2006
|
+
handleAddToCart(data);
|
|
2007
|
+
break;
|
|
2008
|
+
case 'lce:actions.cart_updated':
|
|
2009
|
+
handleCartUpdate(data);
|
|
2010
|
+
break;
|
|
2011
|
+
}
|
|
2012
|
+
});
|
|
1088
2013
|
```
|
|
1089
|
-
- Combines `check` + `build:dev`
|
|
1090
|
-
- Complete code quality check + development build
|
|
1091
|
-
- **Perfect for:** Pre-commit workflow
|
|
1092
2014
|
|
|
1093
|
-
###
|
|
2015
|
+
### Defer Non-Critical Operations
|
|
1094
2016
|
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
2017
|
+
Load SDK after critical page content:
|
|
2018
|
+
|
|
2019
|
+
```html
|
|
2020
|
+
<!-- ❌ Don't load SDK in <head> -->
|
|
2021
|
+
<head>
|
|
2022
|
+
<script src="https://assets-elements.liquidcommerce.us/all/elements.js"></script>
|
|
2023
|
+
</head>
|
|
2024
|
+
|
|
2025
|
+
<!-- ✅ Load SDK with defer or at end of body -->
|
|
2026
|
+
<head>
|
|
2027
|
+
<script defer src="https://assets-elements.liquidcommerce.us/all/elements.js"></script>
|
|
2028
|
+
</head>
|
|
2029
|
+
|
|
2030
|
+
<!-- Or -->
|
|
2031
|
+
<body>
|
|
2032
|
+
<!-- Your page content -->
|
|
2033
|
+
<script src="https://assets-elements.liquidcommerce.us/all/elements.js"></script>
|
|
2034
|
+
</body>
|
|
1098
2035
|
```
|
|
1099
|
-
- Removes `dist/` and `umd/` directories
|
|
1100
|
-
- **Use when:** Build artifacts are corrupted
|
|
1101
2036
|
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
2037
|
+
### Use Auto-Init for Simple Cases
|
|
2038
|
+
|
|
2039
|
+
Auto-init is optimized for performance:
|
|
2040
|
+
|
|
2041
|
+
```html
|
|
2042
|
+
<!-- ✅ Auto-init is the fastest way for simple setups -->
|
|
2043
|
+
<div data-lce-product="00619947000020"></div>
|
|
2044
|
+
<div data-lce-product="00832889005513"></div>
|
|
2045
|
+
|
|
2046
|
+
<script
|
|
2047
|
+
data-liquid-commerce-elements
|
|
2048
|
+
data-token="YOUR_API_KEY"
|
|
2049
|
+
data-env="production"
|
|
2050
|
+
src="https://assets-elements.liquidcommerce.us/all/elements.js"
|
|
2051
|
+
></script>
|
|
1105
2052
|
```
|
|
1106
|
-
- Removes build outputs AND `node_modules/`
|
|
1107
|
-
- Reinstalls all dependencies with `pnpm install`
|
|
1108
|
-
- Runs a fresh production build
|
|
1109
|
-
- **Use when:** Dependency issues or major updates
|
|
1110
2053
|
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
2054
|
+
### Avoid Unnecessary Re-renders
|
|
2055
|
+
|
|
2056
|
+
Don't repeatedly inject the same component:
|
|
2057
|
+
|
|
2058
|
+
```js
|
|
2059
|
+
// ❌ Don't re-inject on every state change
|
|
2060
|
+
function updateProduct() {
|
|
2061
|
+
setProductId(newId);
|
|
2062
|
+
await client.injectProductElement([{ containerId: 'pdp', identifier: newId }]);
|
|
2063
|
+
}
|
|
2064
|
+
|
|
2065
|
+
// ✅ Components update automatically on state changes
|
|
2066
|
+
// Just inject once
|
|
2067
|
+
useEffect(() => {
|
|
2068
|
+
client.injectProductElement([{ containerId: 'pdp', identifier: productId }]);
|
|
2069
|
+
}, []); // Empty deps - inject once
|
|
2070
|
+
|
|
2071
|
+
// Product will auto-update when you call actions
|
|
2072
|
+
await client.actions.cart.addProduct([...]);
|
|
1114
2073
|
```
|
|
1115
|
-
- Generates `CHANGELOG.md` from conventional commits
|
|
1116
|
-
- Uses Angular commit convention
|
|
1117
|
-
- **Use when:** Preparing releases
|
|
1118
2074
|
|
|
1119
|
-
###
|
|
2075
|
+
### Cache Frequently Accessed Data
|
|
1120
2076
|
|
|
1121
|
-
|
|
2077
|
+
```js
|
|
2078
|
+
// ❌ Don't repeatedly fetch the same data
|
|
2079
|
+
async function showCartTotal() {
|
|
2080
|
+
const cart = await client.actions.cart.getDetails();
|
|
2081
|
+
return cart.amounts.total;
|
|
2082
|
+
}
|
|
2083
|
+
|
|
2084
|
+
// ✅ Use UI helpers that auto-update
|
|
2085
|
+
client.ui.cartSubtotal('cart-total-display');
|
|
2086
|
+
client.ui.cartItemsCount('cart-count-display');
|
|
2087
|
+
|
|
2088
|
+
// Or cache and listen to updates
|
|
2089
|
+
let cachedCart = await client.actions.cart.getDetails();
|
|
2090
|
+
window.addEventListener('lce:actions.cart_updated', (event) => {
|
|
2091
|
+
cachedCart = event.detail.data.current;
|
|
2092
|
+
});
|
|
2093
|
+
```
|
|
1122
2094
|
|
|
1123
|
-
|
|
1124
|
-
- **Target:** Modern bundlers (Vite, Webpack, etc.)
|
|
1125
|
-
- **Format:** ES Modules
|
|
1126
|
-
- **Optimizations:** Tree shaking, modern syntax
|
|
1127
|
-
- **Use case:** NPM package imports
|
|
2095
|
+
### Use CDN for Production
|
|
1128
2096
|
|
|
1129
|
-
|
|
1130
|
-
- **Target:** Direct browser usage
|
|
1131
|
-
- **Format:** Universal Module Definition
|
|
1132
|
-
- **Global:** `window.LiquidCommerceElements`
|
|
1133
|
-
- **Optimizations:** Maximum browser compatibility
|
|
1134
|
-
- **Use case:** CDN distribution, `<script>` tags
|
|
2097
|
+
Always use CDN in production for optimal caching:
|
|
1135
2098
|
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
-
|
|
2099
|
+
```js
|
|
2100
|
+
// ✅ CDN (recommended)
|
|
2101
|
+
<script src="https://assets-elements.liquidcommerce.us/all/elements.js"></script>
|
|
1139
2102
|
|
|
1140
|
-
|
|
2103
|
+
// ❌ Don't self-host unless necessary
|
|
2104
|
+
<script src="/static/elements.js"></script>
|
|
2105
|
+
```
|
|
1141
2106
|
|
|
1142
|
-
|
|
1143
|
-
```bash
|
|
1144
|
-
# Start development
|
|
1145
|
-
pnpm run dev
|
|
2107
|
+
### Minimize Theme Complexity
|
|
1146
2108
|
|
|
1147
|
-
|
|
1148
|
-
|
|
2109
|
+
Simpler themes = faster rendering:
|
|
2110
|
+
|
|
2111
|
+
```js
|
|
2112
|
+
// ❌ Don't override every style property
|
|
2113
|
+
customTheme: {
|
|
2114
|
+
global: {
|
|
2115
|
+
colors: { /* 20 color overrides */ },
|
|
2116
|
+
typography: { /* 15 typography overrides */ },
|
|
2117
|
+
shadows: { /* 10 shadow overrides */ },
|
|
2118
|
+
// ... 100 more overrides
|
|
2119
|
+
}
|
|
2120
|
+
}
|
|
2121
|
+
|
|
2122
|
+
// ✅ Override only what's necessary
|
|
2123
|
+
customTheme: {
|
|
2124
|
+
global: {
|
|
2125
|
+
colors: {
|
|
2126
|
+
primary: '#007bff',
|
|
2127
|
+
secondary: '#6c757d'
|
|
2128
|
+
}
|
|
2129
|
+
}
|
|
2130
|
+
}
|
|
1149
2131
|
```
|
|
1150
2132
|
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
2133
|
+
### Monitor Performance
|
|
2134
|
+
|
|
2135
|
+
Track SDK performance in production:
|
|
2136
|
+
|
|
2137
|
+
```js
|
|
2138
|
+
// Measure initialization time
|
|
2139
|
+
const start = performance.now();
|
|
2140
|
+
const client = await Elements('YOUR_API_KEY', { env: 'production' });
|
|
2141
|
+
console.log(`SDK initialized in ${performance.now() - start}ms`);
|
|
2142
|
+
|
|
2143
|
+
// Track component load times
|
|
2144
|
+
window.addEventListener('lce:actions.product_loaded', (event) => {
|
|
2145
|
+
const { loadTime } = event.detail.metadata;
|
|
2146
|
+
console.log(`Product loaded in ${loadTime}ms`);
|
|
2147
|
+
|
|
2148
|
+
// Send to analytics
|
|
2149
|
+
analytics.track('SDK Component Load', {
|
|
2150
|
+
component: 'product',
|
|
2151
|
+
duration: loadTime
|
|
2152
|
+
});
|
|
2153
|
+
});
|
|
2154
|
+
```
|
|
2155
|
+
|
|
2156
|
+
### Production Checklist
|
|
2157
|
+
|
|
2158
|
+
Before going live:
|
|
2159
|
+
|
|
2160
|
+
- ✅ Set `env: 'production'`
|
|
2161
|
+
- ✅ Set `debugMode: 'none'` (or omit)
|
|
2162
|
+
- ✅ Use CDN script URL
|
|
2163
|
+
- ✅ Pin to specific version (optional but recommended)
|
|
2164
|
+
- ✅ Configure proxy if using ad blockers
|
|
2165
|
+
- ✅ Test error handling
|
|
2166
|
+
- ✅ Verify event tracking
|
|
2167
|
+
- ✅ Check cart persistence
|
|
2168
|
+
- ✅ Test on target browsers
|
|
2169
|
+
- ✅ Measure performance metrics
|
|
1155
2170
|
|
|
1156
|
-
|
|
1157
|
-
pnpm run changelog
|
|
2171
|
+
**Production-ready init:**
|
|
1158
2172
|
|
|
1159
|
-
|
|
2173
|
+
```js
|
|
2174
|
+
const client = await Elements('YOUR_PRODUCTION_API_KEY', {
|
|
2175
|
+
env: 'production',
|
|
2176
|
+
debugMode: 'none',
|
|
2177
|
+
customTheme: { /* minimal overrides */ },
|
|
2178
|
+
proxy: { baseUrl: 'https://yourdomain.com/api/proxy' }
|
|
2179
|
+
});
|
|
1160
2180
|
```
|
|
1161
2181
|
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
pnpm run clean:hard
|
|
2182
|
+
**📖 For debugging and troubleshooting:** See [`docs/TROUBLESHOOTING.md`](docs/TROUBLESHOOTING.md) for comprehensive problem-solving guide.
|
|
2183
|
+
|
|
2184
|
+
---
|
|
1166
2185
|
|
|
1167
|
-
|
|
1168
|
-
|
|
2186
|
+
## 🔒 Proxy Configuration
|
|
2187
|
+
|
|
2188
|
+
Route API requests through your server to avoid ad blockers:
|
|
2189
|
+
|
|
2190
|
+
```js
|
|
2191
|
+
const client = await Elements('YOUR_API_KEY', {
|
|
2192
|
+
env: 'production',
|
|
2193
|
+
proxy: {
|
|
2194
|
+
baseUrl: 'https://yourdomain.com/api/liquidcommerce',
|
|
2195
|
+
headers: {
|
|
2196
|
+
'X-Custom-Header': 'value'
|
|
2197
|
+
}
|
|
2198
|
+
}
|
|
2199
|
+
});
|
|
1169
2200
|
```
|
|
1170
2201
|
|
|
2202
|
+
The SDK automatically handles routing and required headers. See [`docs/PROXY.md`](docs/PROXY.md) for complete proxy setup guide with Next.js examples.
|
|
2203
|
+
|
|
2204
|
+
## 📚 Documentation
|
|
2205
|
+
|
|
2206
|
+
**📖 Complete Documentation:**
|
|
2207
|
+
|
|
2208
|
+
- **[Documentation Index](docs/DOCUMENTATION_INDEX.md)** - Complete guide to all documentation
|
|
2209
|
+
- **[Configuration Reference](docs/CONFIGURATION.md)** - All configuration options with TypeScript types
|
|
2210
|
+
- **[Theming Guide](docs/THEMING.md)** - Complete customization reference
|
|
2211
|
+
- **[Actions Reference](docs/ACTIONS.md)** - Programmatic control with business use cases
|
|
2212
|
+
- **[Events Reference](docs/EVENTS.md)** - Event system and tracking guide
|
|
2213
|
+
- **[Troubleshooting Guide](docs/TROUBLESHOOTING.md)** - Common issues and solutions
|
|
2214
|
+
- **[Browser Support](docs/BROWSER_SUPPORT.md)** - Detailed browser compatibility
|
|
2215
|
+
- **[Proxy Setup](docs/PROXY.md)** - Ad blocker avoidance configuration
|
|
2216
|
+
|
|
2217
|
+
---
|
|
2218
|
+
|
|
2219
|
+
## 🏷️ Versioning
|
|
2220
|
+
|
|
2221
|
+
This project uses Semantic Versioning. Two CDN environments are available:
|
|
2222
|
+
|
|
2223
|
+
- **Production:** `https://assets-elements.liquidcommerce.us/all/elements.js` (stable)
|
|
2224
|
+
- **Beta:** `https://assets-elements.liquidcommerce.us/all/beta/elements.js` (pre-release)
|
|
2225
|
+
|
|
1171
2226
|
## 💬 Support
|
|
1172
2227
|
|
|
1173
2228
|
If you need help with your API key, environment selection, or implementation, contact your LiquidCommerce representative.
|