@liquidcommerce/elements-sdk 2.3.0 → 2.4.0
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/dist/index.esm.js +7942 -7627
- package/dist/types/core/google-tag-manager.service.d.ts +1 -0
- package/dist/types/modules/cart/components/cart-footer.component.d.ts +1 -0
- package/dist/types/modules/cart/components/cart-item.component.d.ts +1 -0
- package/dist/types/modules/checkout/components/checkout-summary-section.component.d.ts +2 -0
- package/dist/types/modules/checkout/components/summary/checkout-items.component.d.ts +1 -0
- package/dist/types/modules/ui-components/engraving/engraving-view.component.d.ts +1 -0
- package/docs/ACTIONS.md +1235 -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 +532 -0
- package/docs/PROXY.md +228 -0
- package/docs/THEMING.md +592 -0
- package/docs/TROUBLESHOOTING.md +755 -0
- package/package.json +8 -5
- package/umd/elements.js +1 -1
|
@@ -0,0 +1,755 @@
|
|
|
1
|
+
# Troubleshooting Guide
|
|
2
|
+
|
|
3
|
+
Common issues and solutions for the LiquidCommerce Elements SDK.
|
|
4
|
+
|
|
5
|
+
## SDK Initialization Issues
|
|
6
|
+
|
|
7
|
+
### SDK Not Loading
|
|
8
|
+
|
|
9
|
+
**Symptom:** `Elements is not defined` or SDK not initializing
|
|
10
|
+
|
|
11
|
+
**Causes & Solutions:**
|
|
12
|
+
|
|
13
|
+
#### 1. Script Not Loaded
|
|
14
|
+
|
|
15
|
+
```html
|
|
16
|
+
<!-- ❌ Wrong -->
|
|
17
|
+
<script src="https://assets-elements.liquidcommerce.us/all/elements.js" async></script>
|
|
18
|
+
|
|
19
|
+
<!-- ✅ Correct - Remove async or use onload -->
|
|
20
|
+
<script src="https://assets-elements.liquidcommerce.us/all/elements.js"></script>
|
|
21
|
+
|
|
22
|
+
<!-- Or with async -->
|
|
23
|
+
<script src="https://assets-elements.liquidcommerce.us/all/elements.js" async onload="initSDK()"></script>
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
#### 2. Content Security Policy (CSP)
|
|
27
|
+
|
|
28
|
+
```html
|
|
29
|
+
<!-- Add to your CSP -->
|
|
30
|
+
<meta http-equiv="Content-Security-Policy"
|
|
31
|
+
content="script-src 'self' https://assets-elements.liquidcommerce.us;">
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
#### 3. Ad Blockers
|
|
35
|
+
|
|
36
|
+
**Solution:** Configure a [proxy](./PROXY.md) to route requests through your domain.
|
|
37
|
+
|
|
38
|
+
### Authentication Failures
|
|
39
|
+
|
|
40
|
+
**Symptom:** `401 Unauthorized` or `Invalid API key`
|
|
41
|
+
|
|
42
|
+
**Solutions:**
|
|
43
|
+
|
|
44
|
+
```javascript
|
|
45
|
+
// ✅ Check API key is correct
|
|
46
|
+
const client = await Elements('YOUR_ACTUAL_API_KEY', {
|
|
47
|
+
env: 'production' // Make sure env matches your key
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
// ✅ Verify environment
|
|
51
|
+
// Production keys won't work in development env
|
|
52
|
+
const client = await Elements('PROD_KEY', {
|
|
53
|
+
env: 'production' // Not 'development'
|
|
54
|
+
});
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**Check:**
|
|
58
|
+
- API key is correct
|
|
59
|
+
- Environment matches key (prod key → prod env)
|
|
60
|
+
- Key hasn't been revoked
|
|
61
|
+
- Domain is whitelisted in LiquidCommerce dashboard
|
|
62
|
+
|
|
63
|
+
### Configuration Errors
|
|
64
|
+
|
|
65
|
+
**Symptom:** `Invalid configuration` errors
|
|
66
|
+
|
|
67
|
+
**Common mistakes:**
|
|
68
|
+
|
|
69
|
+
```javascript
|
|
70
|
+
// ❌ Wrong - Invalid env value
|
|
71
|
+
{ env: 'prod' } // Should be 'production'
|
|
72
|
+
|
|
73
|
+
// ❌ Wrong - Invalid debugMode
|
|
74
|
+
{ debugMode: 'debug' } // Should be 'console' or 'panel'
|
|
75
|
+
|
|
76
|
+
// ❌ Wrong - Invalid proxy config
|
|
77
|
+
{ proxy: 'https://...' } // Should be object with baseUrl
|
|
78
|
+
|
|
79
|
+
// ✅ Correct
|
|
80
|
+
{
|
|
81
|
+
env: 'production',
|
|
82
|
+
debugMode: 'none',
|
|
83
|
+
proxy: {
|
|
84
|
+
baseUrl: 'https://...'
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Component Rendering Issues
|
|
90
|
+
|
|
91
|
+
### Components Not Appearing
|
|
92
|
+
|
|
93
|
+
**Symptom:** Container div is empty
|
|
94
|
+
|
|
95
|
+
**Debugging steps:**
|
|
96
|
+
|
|
97
|
+
```javascript
|
|
98
|
+
// 1. Check container exists
|
|
99
|
+
const container = document.getElementById('product-container');
|
|
100
|
+
console.log('Container:', container); // Should not be null
|
|
101
|
+
|
|
102
|
+
// 2. Wait for DOM
|
|
103
|
+
window.addEventListener('DOMContentLoaded', async () => {
|
|
104
|
+
const client = await Elements('YOUR_API_KEY', { env: 'production' });
|
|
105
|
+
await client.injectProductElement([
|
|
106
|
+
{ containerId: 'product-container', identifier: 'product-123' }
|
|
107
|
+
]);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// 3. Monitor product loading
|
|
111
|
+
window.addEventListener('lce:actions.product_loaded', (event) => {
|
|
112
|
+
console.log('Product loaded:', event.detail.data);
|
|
113
|
+
});
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
**Common issues:**
|
|
117
|
+
- Container doesn't exist when SDK tries to inject
|
|
118
|
+
- Product identifier is invalid
|
|
119
|
+
- Product not available in current environment
|
|
120
|
+
|
|
121
|
+
### Styling Issues
|
|
122
|
+
|
|
123
|
+
**Symptom:** Components look broken or unstyled
|
|
124
|
+
|
|
125
|
+
**Solutions:**
|
|
126
|
+
|
|
127
|
+
```javascript
|
|
128
|
+
// 1. Check for CSS conflicts
|
|
129
|
+
// Look for these in your CSS:
|
|
130
|
+
// - * { all: unset }
|
|
131
|
+
// - Overly broad selectors affecting [data-lce-*]
|
|
132
|
+
|
|
133
|
+
// 2. Verify theme config
|
|
134
|
+
const client = await Elements('YOUR_API_KEY', {
|
|
135
|
+
customTheme: {
|
|
136
|
+
global: {
|
|
137
|
+
colors: {
|
|
138
|
+
primary: '#007bff' // Valid hex color
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
// 3. Check z-index conflicts
|
|
145
|
+
// SDK uses z-index 1000-1070 for modals/drawers
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Layout Issues
|
|
149
|
+
|
|
150
|
+
**Symptom:** Components overlapping or misaligned
|
|
151
|
+
|
|
152
|
+
**Solutions:**
|
|
153
|
+
|
|
154
|
+
```css
|
|
155
|
+
/* Ensure container has proper display */
|
|
156
|
+
#product-container {
|
|
157
|
+
display: block;
|
|
158
|
+
width: 100%;
|
|
159
|
+
min-height: 400px; /* Prevent collapsing */
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/* Fix flexbox/grid conflicts */
|
|
163
|
+
#product-container > * {
|
|
164
|
+
flex: initial;
|
|
165
|
+
grid-column: initial;
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Event Handling Issues
|
|
170
|
+
|
|
171
|
+
### Events Not Firing
|
|
172
|
+
|
|
173
|
+
**Symptom:** Event listeners not being called
|
|
174
|
+
|
|
175
|
+
**Solutions:**
|
|
176
|
+
|
|
177
|
+
```javascript
|
|
178
|
+
// ✅ Correct - Set up listener BEFORE action
|
|
179
|
+
window.addEventListener('lce:actions.cart_updated', handleUpdate);
|
|
180
|
+
await client.actions.cart.addProduct([...]);
|
|
181
|
+
|
|
182
|
+
// ❌ Wrong - Listener after action (might miss event)
|
|
183
|
+
await client.actions.cart.addProduct([...]);
|
|
184
|
+
window.addEventListener('lce:actions.cart_updated', handleUpdate);
|
|
185
|
+
|
|
186
|
+
// ✅ Use capture phase for guaranteed delivery
|
|
187
|
+
window.addEventListener('lce:actions.cart_updated', handleUpdate, true);
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Event Data Missing
|
|
191
|
+
|
|
192
|
+
**Symptom:** `event.detail.data` is undefined
|
|
193
|
+
|
|
194
|
+
**Check:**
|
|
195
|
+
|
|
196
|
+
```javascript
|
|
197
|
+
window.addEventListener('lce:actions.cart_updated', (event) => {
|
|
198
|
+
// ❌ Wrong
|
|
199
|
+
const data = event.data;
|
|
200
|
+
|
|
201
|
+
// ✅ Correct
|
|
202
|
+
const data = event.detail.data;
|
|
203
|
+
|
|
204
|
+
console.log('Cart data:', data);
|
|
205
|
+
});
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Multiple Event Firings
|
|
209
|
+
|
|
210
|
+
**Symptom:** Event listener called multiple times unexpectedly
|
|
211
|
+
|
|
212
|
+
**Solution:**
|
|
213
|
+
|
|
214
|
+
```javascript
|
|
215
|
+
// ❌ Problem - Adding listener multiple times
|
|
216
|
+
function setupListeners() {
|
|
217
|
+
window.addEventListener('lce:actions.cart_updated', handleUpdate);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// ✅ Solution - Remove before adding
|
|
221
|
+
function setupListeners() {
|
|
222
|
+
window.removeEventListener('lce:actions.cart_updated', handleUpdate);
|
|
223
|
+
window.addEventListener('lce:actions.cart_updated', handleUpdate);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Or use once option
|
|
227
|
+
window.addEventListener('lce:actions.cart_updated', handleUpdate, { once: true });
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## Cart & Checkout Issues
|
|
231
|
+
|
|
232
|
+
### Cart Not Persisting
|
|
233
|
+
|
|
234
|
+
**Symptom:** Cart clears on page reload
|
|
235
|
+
|
|
236
|
+
**Causes:**
|
|
237
|
+
|
|
238
|
+
```javascript
|
|
239
|
+
// 1. LocalStorage disabled
|
|
240
|
+
if (!('localStorage' in window)) {
|
|
241
|
+
console.error('LocalStorage not available');
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// 2. Private/Incognito mode
|
|
245
|
+
// LocalStorage is disabled in private browsing
|
|
246
|
+
|
|
247
|
+
// 3. Storage quota exceeded
|
|
248
|
+
try {
|
|
249
|
+
localStorage.setItem('test', 'test');
|
|
250
|
+
} catch (e) {
|
|
251
|
+
console.error('Storage error:', e);
|
|
252
|
+
}
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
**Solutions:**
|
|
256
|
+
- Ask users to enable cookies/storage
|
|
257
|
+
- Warn users about private mode limitations
|
|
258
|
+
- Clear old localStorage data
|
|
259
|
+
|
|
260
|
+
### Checkout Failing
|
|
261
|
+
|
|
262
|
+
**Symptom:** Checkout submit errors
|
|
263
|
+
|
|
264
|
+
**Common causes:**
|
|
265
|
+
|
|
266
|
+
```javascript
|
|
267
|
+
// Listen for specific errors
|
|
268
|
+
window.addEventListener('lce:actions.checkout_submit_failed', (event) => {
|
|
269
|
+
const { error, reason } = event.detail.data;
|
|
270
|
+
|
|
271
|
+
if (reason.includes('payment')) {
|
|
272
|
+
// Payment declined
|
|
273
|
+
showPaymentError();
|
|
274
|
+
} else if (reason.includes('inventory')) {
|
|
275
|
+
// Out of stock
|
|
276
|
+
showInventoryError();
|
|
277
|
+
} else if (reason.includes('address')) {
|
|
278
|
+
// Invalid address
|
|
279
|
+
showAddressError();
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
**Debug steps:**
|
|
285
|
+
1. Check address is set: `client.actions.address.getDetails()`
|
|
286
|
+
2. Check cart has items: `client.actions.cart.getDetails()`
|
|
287
|
+
3. Verify payment info is complete
|
|
288
|
+
4. Check for form validation errors
|
|
289
|
+
5. Look for network errors in console
|
|
290
|
+
|
|
291
|
+
### Promo Code Issues
|
|
292
|
+
|
|
293
|
+
**Symptom:** Promo codes not applying
|
|
294
|
+
|
|
295
|
+
**Debug:**
|
|
296
|
+
|
|
297
|
+
```javascript
|
|
298
|
+
// Listen for promo failures
|
|
299
|
+
window.addEventListener('lce:actions.cart_promo_code_failed', (event) => {
|
|
300
|
+
const { error } = event.detail.data;
|
|
301
|
+
console.error('Promo failed:', error);
|
|
302
|
+
|
|
303
|
+
// Common errors:
|
|
304
|
+
// - "Promo code expired"
|
|
305
|
+
// - "Cart minimum not met"
|
|
306
|
+
// - "Promo code invalid"
|
|
307
|
+
// - "Promo already applied"
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
// Verify promo is active
|
|
311
|
+
// Check LiquidCommerce dashboard for promo settings
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
## Address Validation Issues
|
|
315
|
+
|
|
316
|
+
### Google Places Not Working
|
|
317
|
+
|
|
318
|
+
**Symptom:** Address autocomplete not appearing
|
|
319
|
+
|
|
320
|
+
**Causes:**
|
|
321
|
+
|
|
322
|
+
```javascript
|
|
323
|
+
// 1. Google Places API key missing/invalid
|
|
324
|
+
// Check browser console for Google API errors
|
|
325
|
+
|
|
326
|
+
// 2. Domain not authorized
|
|
327
|
+
// Add your domain to Google Cloud Console
|
|
328
|
+
|
|
329
|
+
// 3. API not enabled
|
|
330
|
+
// Enable Places API in Google Cloud Console
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
### Manual Address Issues
|
|
334
|
+
|
|
335
|
+
**Symptom:** Manual address not working
|
|
336
|
+
|
|
337
|
+
**Solutions:**
|
|
338
|
+
|
|
339
|
+
```javascript
|
|
340
|
+
// Ensure coordinates are valid
|
|
341
|
+
const isValidLat = lat >= -90 && lat <= 90;
|
|
342
|
+
const isValidLng = lng >= -180 && lng <= 180;
|
|
343
|
+
|
|
344
|
+
if (!isValidLat || !isValidLng) {
|
|
345
|
+
console.error('Invalid coordinates');
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// Use proper format
|
|
349
|
+
await client.actions.address.setAddressManually(
|
|
350
|
+
{
|
|
351
|
+
one: '123 Main St',
|
|
352
|
+
two: 'Apt 4B', // Optional but must be string
|
|
353
|
+
city: 'New York',
|
|
354
|
+
state: 'NY',
|
|
355
|
+
zip: '10001',
|
|
356
|
+
country: 'United States'
|
|
357
|
+
},
|
|
358
|
+
{
|
|
359
|
+
lat: 40.7505045,
|
|
360
|
+
long: -73.9934387 // Note: "long" not "lng"
|
|
361
|
+
}
|
|
362
|
+
);
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
## Network & API Issues
|
|
366
|
+
|
|
367
|
+
### CORS Errors
|
|
368
|
+
|
|
369
|
+
**Symptom:** `Access-Control-Allow-Origin` errors
|
|
370
|
+
|
|
371
|
+
**Solutions:**
|
|
372
|
+
|
|
373
|
+
```javascript
|
|
374
|
+
// 1. Use proxy to avoid CORS
|
|
375
|
+
const client = await Elements('YOUR_API_KEY', {
|
|
376
|
+
proxy: {
|
|
377
|
+
baseUrl: 'https://yourdomain.com/api/liquidcommerce'
|
|
378
|
+
}
|
|
379
|
+
});
|
|
380
|
+
|
|
381
|
+
// 2. Check domain whitelist
|
|
382
|
+
// Verify your domain is whitelisted in LiquidCommerce dashboard
|
|
383
|
+
|
|
384
|
+
// 3. Development workaround
|
|
385
|
+
// Use browser extension to disable CORS (dev only!)
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
### Slow API Responses
|
|
389
|
+
|
|
390
|
+
**Symptom:** Components take long to load
|
|
391
|
+
|
|
392
|
+
**Debug:**
|
|
393
|
+
|
|
394
|
+
```javascript
|
|
395
|
+
// 1. Enable debug mode
|
|
396
|
+
const client = await Elements('YOUR_API_KEY', {
|
|
397
|
+
debugMode: 'console'
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
// 2. Check network tab
|
|
401
|
+
// Look for slow API calls
|
|
402
|
+
|
|
403
|
+
// 3. Monitor for failures
|
|
404
|
+
window.addEventListener('lce:actions.cart_failed', (event) => {
|
|
405
|
+
console.warn('Cart operation failed:', event.detail);
|
|
406
|
+
});
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
**Solutions:**
|
|
410
|
+
- Configure proxy for better routing
|
|
411
|
+
- Check internet connection
|
|
412
|
+
- Verify API status (LiquidCommerce status page)
|
|
413
|
+
- Use CDN for SDK script (automatic caching)
|
|
414
|
+
|
|
415
|
+
### API Rate Limiting
|
|
416
|
+
|
|
417
|
+
**Symptom:** `429 Too Many Requests`
|
|
418
|
+
|
|
419
|
+
**Solutions:**
|
|
420
|
+
|
|
421
|
+
```javascript
|
|
422
|
+
// Implement retry logic
|
|
423
|
+
async function addToCartWithRetry(params, maxRetries = 3) {
|
|
424
|
+
for (let i = 0; i < maxRetries; i++) {
|
|
425
|
+
try {
|
|
426
|
+
await client.actions.cart.addProduct(params);
|
|
427
|
+
return;
|
|
428
|
+
} catch (error) {
|
|
429
|
+
if (error.status === 429) {
|
|
430
|
+
// Wait before retry
|
|
431
|
+
await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
|
|
432
|
+
} else {
|
|
433
|
+
throw error;
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
## Performance Issues
|
|
441
|
+
|
|
442
|
+
### Slow Page Load
|
|
443
|
+
|
|
444
|
+
**Symptom:** SDK slows down page load
|
|
445
|
+
|
|
446
|
+
**Solutions:**
|
|
447
|
+
|
|
448
|
+
```html
|
|
449
|
+
<!-- 1. Use defer attribute -->
|
|
450
|
+
<script defer src="https://assets-elements.liquidcommerce.us/all/elements.js"></script>
|
|
451
|
+
|
|
452
|
+
<!-- 2. Load at end of body -->
|
|
453
|
+
<body>
|
|
454
|
+
<!-- Page content -->
|
|
455
|
+
<script src="https://assets-elements.liquidcommerce.us/all/elements.js"></script>
|
|
456
|
+
</body>
|
|
457
|
+
|
|
458
|
+
<!-- 3. Lazy load components -->
|
|
459
|
+
<script>
|
|
460
|
+
window.addEventListener('load', async () => {
|
|
461
|
+
const client = await Elements('YOUR_API_KEY', { env: 'production' });
|
|
462
|
+
// Initialize after page load
|
|
463
|
+
});
|
|
464
|
+
</script>
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
### Memory Leaks
|
|
468
|
+
|
|
469
|
+
**Symptom:** Page becomes slow over time
|
|
470
|
+
|
|
471
|
+
**Solutions:**
|
|
472
|
+
|
|
473
|
+
```javascript
|
|
474
|
+
// Remove event listeners when done
|
|
475
|
+
function cleanup() {
|
|
476
|
+
window.removeEventListener('lce:actions.cart_updated', handleUpdate);
|
|
477
|
+
window.removeEventListener('lce:actions.product_loaded', handleProduct);
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
// In React/Vue
|
|
481
|
+
useEffect(() => {
|
|
482
|
+
window.addEventListener('lce:actions.cart_updated', handleUpdate);
|
|
483
|
+
|
|
484
|
+
return () => {
|
|
485
|
+
window.removeEventListener('lce:actions.cart_updated', handleUpdate);
|
|
486
|
+
};
|
|
487
|
+
}, []);
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
### High CPU Usage
|
|
491
|
+
|
|
492
|
+
**Symptom:** Browser tab using excessive CPU
|
|
493
|
+
|
|
494
|
+
**Check:**
|
|
495
|
+
|
|
496
|
+
```javascript
|
|
497
|
+
// 1. Disable debug mode in production
|
|
498
|
+
{
|
|
499
|
+
debugMode: 'none' // Not 'panel'
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
// 2. Minimize theme complexity
|
|
503
|
+
{
|
|
504
|
+
customTheme: {
|
|
505
|
+
global: {
|
|
506
|
+
colors: {
|
|
507
|
+
primary: '#007bff' // Only override what's needed
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
// 3. Reduce event listeners
|
|
514
|
+
// Use event delegation instead of many listeners
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
## Mobile-Specific Issues
|
|
518
|
+
|
|
519
|
+
### Touch Events Not Working
|
|
520
|
+
|
|
521
|
+
**Symptom:** Buttons/interactions not responding on mobile
|
|
522
|
+
|
|
523
|
+
**Check:**
|
|
524
|
+
|
|
525
|
+
```css
|
|
526
|
+
/* Ensure touch targets are large enough */
|
|
527
|
+
button {
|
|
528
|
+
min-height: 44px; /* iOS minimum */
|
|
529
|
+
min-width: 44px;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
/* Fix iOS double-tap zoom */
|
|
533
|
+
button {
|
|
534
|
+
touch-action: manipulation;
|
|
535
|
+
}
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
### Viewport Issues
|
|
539
|
+
|
|
540
|
+
**Symptom:** Components too small or zoomed on mobile
|
|
541
|
+
|
|
542
|
+
**Solution:**
|
|
543
|
+
|
|
544
|
+
```html
|
|
545
|
+
<!-- Ensure viewport meta tag is present -->
|
|
546
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
### Keyboard Covering Input
|
|
550
|
+
|
|
551
|
+
**Symptom:** Keyboard covers form fields on mobile
|
|
552
|
+
|
|
553
|
+
**Solution:**
|
|
554
|
+
|
|
555
|
+
```javascript
|
|
556
|
+
// SDK handles this automatically, but if issues persist:
|
|
557
|
+
document.addEventListener('focusin', (e) => {
|
|
558
|
+
if (e.target.tagName === 'INPUT') {
|
|
559
|
+
setTimeout(() => {
|
|
560
|
+
e.target.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
|
561
|
+
}, 300);
|
|
562
|
+
}
|
|
563
|
+
});
|
|
564
|
+
```
|
|
565
|
+
|
|
566
|
+
## Framework-Specific Issues
|
|
567
|
+
|
|
568
|
+
### React Issues
|
|
569
|
+
|
|
570
|
+
**Problem:** SDK initializes multiple times
|
|
571
|
+
|
|
572
|
+
**Solution:**
|
|
573
|
+
|
|
574
|
+
```jsx
|
|
575
|
+
import { useEffect, useRef } from 'react';
|
|
576
|
+
|
|
577
|
+
function App() {
|
|
578
|
+
const clientRef = useRef(null);
|
|
579
|
+
|
|
580
|
+
useEffect(() => {
|
|
581
|
+
async function init() {
|
|
582
|
+
if (!clientRef.current) {
|
|
583
|
+
clientRef.current = await Elements('YOUR_API_KEY', { env: 'production' });
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
init();
|
|
587
|
+
}, []); // Empty deps - initialize once
|
|
588
|
+
|
|
589
|
+
return <div id="product-container"></div>;
|
|
590
|
+
}
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
### Next.js Issues
|
|
594
|
+
|
|
595
|
+
**Problem:** `window is not defined` (SSR)
|
|
596
|
+
|
|
597
|
+
**Solution:**
|
|
598
|
+
|
|
599
|
+
```javascript
|
|
600
|
+
// pages/product.js
|
|
601
|
+
import { useEffect } from 'react';
|
|
602
|
+
|
|
603
|
+
export default function Product() {
|
|
604
|
+
useEffect(() => {
|
|
605
|
+
// Only run on client
|
|
606
|
+
async function init() {
|
|
607
|
+
if (typeof window !== 'undefined') {
|
|
608
|
+
const { Elements } = await import('@liquidcommerce/elements-sdk');
|
|
609
|
+
const client = await Elements(process.env.NEXT_PUBLIC_LCE_API_KEY, {
|
|
610
|
+
env: 'production'
|
|
611
|
+
});
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
init();
|
|
615
|
+
}, []);
|
|
616
|
+
|
|
617
|
+
return <div id="product-container"></div>;
|
|
618
|
+
}
|
|
619
|
+
```
|
|
620
|
+
|
|
621
|
+
### Vue Issues
|
|
622
|
+
|
|
623
|
+
**Problem:** Components not reactive
|
|
624
|
+
|
|
625
|
+
**Solution:**
|
|
626
|
+
|
|
627
|
+
```vue
|
|
628
|
+
<script setup>
|
|
629
|
+
import { onMounted, ref } from 'vue';
|
|
630
|
+
|
|
631
|
+
const cartData = ref(null);
|
|
632
|
+
|
|
633
|
+
onMounted(async () => {
|
|
634
|
+
const client = await Elements(import.meta.env.VITE_LCE_API_KEY, {
|
|
635
|
+
env: 'production'
|
|
636
|
+
});
|
|
637
|
+
|
|
638
|
+
window.addEventListener('lce:actions.cart_updated', (event) => {
|
|
639
|
+
cartData.value = event.detail.data; // Vue reactivity
|
|
640
|
+
});
|
|
641
|
+
});
|
|
642
|
+
</script>
|
|
643
|
+
```
|
|
644
|
+
|
|
645
|
+
## Browser-Specific Issues
|
|
646
|
+
|
|
647
|
+
### Safari Issues
|
|
648
|
+
|
|
649
|
+
**Problem:** LocalStorage quota exceeded
|
|
650
|
+
|
|
651
|
+
**Solution:**
|
|
652
|
+
|
|
653
|
+
```javascript
|
|
654
|
+
try {
|
|
655
|
+
localStorage.setItem('lce_cart', JSON.stringify(cart));
|
|
656
|
+
} catch (e) {
|
|
657
|
+
if (e.name === 'QuotaExceededError') {
|
|
658
|
+
// Clear old data
|
|
659
|
+
localStorage.removeItem('lce_old_cart');
|
|
660
|
+
// Retry
|
|
661
|
+
localStorage.setItem('lce_cart', JSON.stringify(cart));
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
```
|
|
665
|
+
|
|
666
|
+
### Firefox Issues
|
|
667
|
+
|
|
668
|
+
**Problem:** Different rendering/layout
|
|
669
|
+
|
|
670
|
+
**Solution:**
|
|
671
|
+
|
|
672
|
+
```css
|
|
673
|
+
/* Add Firefox-specific fixes if needed */
|
|
674
|
+
@-moz-document url-prefix() {
|
|
675
|
+
.lce-component {
|
|
676
|
+
/* Firefox-specific styles */
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
```
|
|
680
|
+
|
|
681
|
+
## Debugging Tools
|
|
682
|
+
|
|
683
|
+
### Enable Debug Mode
|
|
684
|
+
|
|
685
|
+
```javascript
|
|
686
|
+
const client = await Elements('YOUR_API_KEY', {
|
|
687
|
+
debugMode: 'panel' // Shows visual debug panel
|
|
688
|
+
});
|
|
689
|
+
```
|
|
690
|
+
|
|
691
|
+
### Check SDK State
|
|
692
|
+
|
|
693
|
+
```javascript
|
|
694
|
+
// Get current state
|
|
695
|
+
const cart = await client.actions.cart.getDetails();
|
|
696
|
+
const address = await client.actions.address.getDetails();
|
|
697
|
+
const checkout = await client.actions.checkout.getDetails();
|
|
698
|
+
|
|
699
|
+
console.log('Cart:', cart);
|
|
700
|
+
console.log('Address:', address);
|
|
701
|
+
console.log('Checkout:', checkout);
|
|
702
|
+
```
|
|
703
|
+
|
|
704
|
+
### Monitor All Events
|
|
705
|
+
|
|
706
|
+
```javascript
|
|
707
|
+
// Log all SDK events
|
|
708
|
+
window.elements.onAllActions((data, metadata) => {
|
|
709
|
+
console.log('Action:', metadata.eventName, data);
|
|
710
|
+
});
|
|
711
|
+
|
|
712
|
+
window.elements.onAllForms((data, metadata) => {
|
|
713
|
+
console.log('Form:', metadata.eventName, data);
|
|
714
|
+
});
|
|
715
|
+
```
|
|
716
|
+
|
|
717
|
+
### Network Inspection
|
|
718
|
+
|
|
719
|
+
```javascript
|
|
720
|
+
// Monitor cart operations
|
|
721
|
+
window.addEventListener('lce:actions.cart_loaded', (event) => {
|
|
722
|
+
console.log('Cart loaded:', event.detail.data);
|
|
723
|
+
});
|
|
724
|
+
|
|
725
|
+
window.addEventListener('lce:actions.cart_failed', (event) => {
|
|
726
|
+
console.error('Cart operation failed:', event.detail.data);
|
|
727
|
+
});
|
|
728
|
+
```
|
|
729
|
+
|
|
730
|
+
## Getting Help
|
|
731
|
+
|
|
732
|
+
If you're still experiencing issues:
|
|
733
|
+
|
|
734
|
+
1. **Check the console** for error messages
|
|
735
|
+
2. **Enable debug mode** to see detailed logs
|
|
736
|
+
3. **Check network tab** for failed requests
|
|
737
|
+
4. **Verify configuration** matches documentation
|
|
738
|
+
5. **Test in incognito mode** to rule out extensions
|
|
739
|
+
6. **Try a different browser** to isolate browser-specific issues
|
|
740
|
+
7. **Check LiquidCommerce status page** for API issues
|
|
741
|
+
8. **Contact support** with:
|
|
742
|
+
- SDK version
|
|
743
|
+
- Browser and OS
|
|
744
|
+
- Console errors
|
|
745
|
+
- Steps to reproduce
|
|
746
|
+
- Minimal code example
|
|
747
|
+
|
|
748
|
+
## Related Documentation
|
|
749
|
+
|
|
750
|
+
- [Configuration Reference](./CONFIGURATION.md) - Configuration options
|
|
751
|
+
- [Actions Reference](./ACTIONS.md) - Programmatic control
|
|
752
|
+
- [Events Reference](./EVENTS.md) - Event system
|
|
753
|
+
- [Browser Support](./BROWSER_SUPPORT.md) - Browser compatibility
|
|
754
|
+
- [Proxy Setup](./PROXY.md) - Proxy configuration
|
|
755
|
+
|