@liquidcommerce/elements-sdk 2.6.0-beta.40 → 2.6.0-beta.42
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 +79 -171
- package/dist/index.checkout.esm.js +6814 -6806
- package/dist/index.esm.js +10596 -10567
- package/dist/types/auto-initialize/shared-utils.d.ts +5 -0
- package/dist/types/core/base-component.service.d.ts +2 -1
- package/dist/types/core/pubsub/interfaces/checkout.interface.d.ts +1 -0
- package/dist/types/interfaces/core.interface.d.ts +5 -4
- package/dist/types/modules/checkout/components/checkout-stripe-form.component.d.ts +2 -1
- package/dist/types/modules/ui-components/lce-element/lce-element.component.d.ts +2 -1
- package/dist/types/utils/dom-compat.d.ts +2 -0
- package/docs/gitbook/actions.md +964 -0
- package/docs/gitbook/address.md +48 -0
- package/docs/gitbook/cart.md +65 -0
- package/docs/gitbook/checkout.md +131 -0
- package/docs/gitbook/events.md +1765 -0
- package/docs/gitbook/overview.md +166 -0
- package/docs/gitbook/product.md +64 -0
- package/docs/gitbook/quick-start-guide.md +393 -0
- package/docs/v1/README.md +210 -0
- package/docs/v1/api/actions/address-actions.md +281 -0
- package/docs/v1/api/actions/cart-actions.md +337 -0
- package/docs/v1/api/actions/checkout-actions.md +387 -0
- package/docs/v1/api/actions/product-actions.md +115 -0
- package/docs/v1/api/client.md +482 -0
- package/docs/v1/api/configuration.md +1 -0
- package/docs/v1/api/injection-methods.md +247 -0
- package/docs/v1/api/typescript-types.md +1 -0
- package/docs/v1/api/ui-helpers.md +200 -0
- package/docs/v1/examples/advanced-patterns.md +96 -0
- package/docs/v1/examples/checkout-flow.md +91 -0
- package/docs/v1/examples/custom-theming.md +63 -0
- package/docs/v1/examples/multi-product-page.md +90 -0
- package/docs/v1/examples/simple-product-page.md +89 -0
- package/docs/v1/getting-started/concepts.md +507 -0
- package/docs/v1/getting-started/installation.md +328 -0
- package/docs/v1/getting-started/quick-start.md +405 -0
- package/docs/v1/guides/address-component.md +431 -0
- package/docs/v1/guides/best-practices.md +324 -0
- package/docs/v1/guides/cart-component.md +737 -0
- package/docs/v1/guides/checkout-component.md +672 -0
- package/docs/v1/guides/events.md +926 -0
- package/docs/v1/guides/product-component.md +686 -0
- package/docs/v1/guides/product-list-component.md +598 -0
- package/docs/v1/guides/theming.md +216 -0
- package/docs/v1/integration/angular.md +39 -0
- package/docs/v1/integration/laravel.md +41 -0
- package/docs/v1/integration/nextjs.md +60 -0
- package/docs/v1/integration/proxy-setup.md +89 -0
- package/docs/v1/integration/react.md +64 -0
- package/docs/v1/integration/vanilla-js.md +84 -0
- package/docs/v1/integration/vue.md +34 -0
- package/docs/v1/reference/browser-support.md +44 -0
- package/docs/v1/reference/error-handling.md +70 -0
- package/docs/v1/reference/performance.md +54 -0
- package/docs/v1/reference/troubleshooting.md +64 -0
- package/package.json +1 -1
- package/docs/actions.md +0 -320
- package/docs/address.md +0 -242
- package/docs/browser-support.md +0 -279
- package/docs/cart.md +0 -387
- package/docs/checkout.md +0 -420
- package/docs/configuration.md +0 -1017
- package/docs/events.md +0 -181
- package/docs/product-list.md +0 -311
- package/docs/product.md +0 -250
- package/docs/proxy.md +0 -228
- package/docs/theming.md +0 -682
- package/docs/troubleshooting.md +0 -793
package/docs/product.md
DELETED
|
@@ -1,250 +0,0 @@
|
|
|
1
|
-
# Product
|
|
2
|
-
|
|
3
|
-
The product element is the heart of the SDK - it displays product information, handles size and variant selection, shows real-time pricing based on delivery location, and lets customers add items to their cart.
|
|
4
|
-
|
|
5
|
-
## Overview
|
|
6
|
-
|
|
7
|
-
The product element renders a complete product card with:
|
|
8
|
-
- Product imagery and details
|
|
9
|
-
- Size/variant selection
|
|
10
|
-
- Real-time pricing based on delivery address
|
|
11
|
-
- Fulfillment options (shipping vs on-demand delivery)
|
|
12
|
-
- Quantity controls
|
|
13
|
-
- Add to cart functionality
|
|
14
|
-
- Personalization/engraving options (when available)
|
|
15
|
-
|
|
16
|
-
The component automatically adapts to the customer's delivery address, showing only available fulfillment options and location-specific pricing.
|
|
17
|
-
|
|
18
|
-
---
|
|
19
|
-
|
|
20
|
-
## Declarative Setup (HTML Attributes)
|
|
21
|
-
|
|
22
|
-
Add products to your page without writing JavaScript. Choose the method that fits your use case.
|
|
23
|
-
|
|
24
|
-
### Method 1: Direct Attributes
|
|
25
|
-
|
|
26
|
-
Best for static pages with known products. Add products directly in the script tag:
|
|
27
|
-
|
|
28
|
-
```html
|
|
29
|
-
<div id="product-1"></div>
|
|
30
|
-
<div id="product-2"></div>
|
|
31
|
-
|
|
32
|
-
<script
|
|
33
|
-
defer
|
|
34
|
-
type="text/javascript"
|
|
35
|
-
data-liquid-commerce-elements
|
|
36
|
-
data-token="YOUR_API_KEY"
|
|
37
|
-
data-env="production"
|
|
38
|
-
data-container-1="product-1"
|
|
39
|
-
data-product-1="00619947000020"
|
|
40
|
-
data-container-2="product-2"
|
|
41
|
-
data-product-2="00832889005513"
|
|
42
|
-
src="https://assets-elements.liquidcommerce.us/all/elements.js"
|
|
43
|
-
></script>
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
The pattern is `data-container-N` paired with `data-product-N` where N is any number.
|
|
47
|
-
|
|
48
|
-
### Method 2: JSON Configuration
|
|
49
|
-
|
|
50
|
-
Best for CMS platforms and dynamic content. Configure products via a JSON script block:
|
|
51
|
-
|
|
52
|
-
```html
|
|
53
|
-
<div id="product-1"></div>
|
|
54
|
-
<div id="product-2"></div>
|
|
55
|
-
|
|
56
|
-
<script data-liquid-commerce-elements-products type="application/json">
|
|
57
|
-
[
|
|
58
|
-
{ "containerId": "product-1", "identifier": "00619947000020" },
|
|
59
|
-
{ "containerId": "product-2", "identifier": "00832889005513" }
|
|
60
|
-
]
|
|
61
|
-
</script>
|
|
62
|
-
|
|
63
|
-
<script
|
|
64
|
-
defer
|
|
65
|
-
type="text/javascript"
|
|
66
|
-
data-liquid-commerce-elements
|
|
67
|
-
data-token="YOUR_API_KEY"
|
|
68
|
-
data-env="production"
|
|
69
|
-
src="https://assets-elements.liquidcommerce.us/all/elements.js"
|
|
70
|
-
></script>
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
This approach works well with templating engines and server-side rendering.
|
|
74
|
-
|
|
75
|
-
### Method 3: Annotated Elements
|
|
76
|
-
|
|
77
|
-
Best for product grids and lists. Mark any div with a data attribute:
|
|
78
|
-
|
|
79
|
-
```html
|
|
80
|
-
<div class="product-grid">
|
|
81
|
-
<div data-lce-product="00619947000020"></div>
|
|
82
|
-
<div data-lce-product="00832889005513"></div>
|
|
83
|
-
<div data-lce-product="00851468007252"></div>
|
|
84
|
-
</div>
|
|
85
|
-
|
|
86
|
-
<script
|
|
87
|
-
defer
|
|
88
|
-
type="text/javascript"
|
|
89
|
-
data-liquid-commerce-elements
|
|
90
|
-
data-token="YOUR_API_KEY"
|
|
91
|
-
data-env="production"
|
|
92
|
-
src="https://assets-elements.liquidcommerce.us/all/elements.js"
|
|
93
|
-
></script>
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
The SDK automatically finds and initializes all elements with `data-lce-product`.
|
|
97
|
-
|
|
98
|
-
---
|
|
99
|
-
|
|
100
|
-
## Programmatic Setup (JavaScript API)
|
|
101
|
-
|
|
102
|
-
For full control, inject products using the client API.
|
|
103
|
-
|
|
104
|
-
### Basic Injection
|
|
105
|
-
|
|
106
|
-
```javascript
|
|
107
|
-
const client = await Elements('YOUR_API_KEY', { env: 'production' });
|
|
108
|
-
|
|
109
|
-
const components = await client.injectProductElement([
|
|
110
|
-
{ containerId: 'pdp-1', identifier: '00619947000020' },
|
|
111
|
-
{ containerId: 'pdp-2', identifier: '00832889005513' }
|
|
112
|
-
]);
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
### Parameters
|
|
116
|
-
|
|
117
|
-
| Parameter | Type | Required | Description |
|
|
118
|
-
|-----------|------|----------|-------------|
|
|
119
|
-
| `containerId` | string | Yes | ID of the container element |
|
|
120
|
-
| `identifier` | string | Yes | Product UPC, ID, or Salsify grouping ID |
|
|
121
|
-
|
|
122
|
-
### Return Value
|
|
123
|
-
|
|
124
|
-
Returns `IInjectedComponent[]` - an array of component wrappers with these methods:
|
|
125
|
-
|
|
126
|
-
```javascript
|
|
127
|
-
// Get the container element
|
|
128
|
-
const element = components[0].getElement();
|
|
129
|
-
|
|
130
|
-
// Get the component type
|
|
131
|
-
const type = components[0].getType(); // 'product'
|
|
132
|
-
|
|
133
|
-
// Force a re-render
|
|
134
|
-
components[0].rerender();
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
### Dynamic Product Loading
|
|
138
|
-
|
|
139
|
-
Load products dynamically based on user actions:
|
|
140
|
-
|
|
141
|
-
```javascript
|
|
142
|
-
// Load product when user clicks a button
|
|
143
|
-
document.querySelector('#load-product').addEventListener('click', async () => {
|
|
144
|
-
await client.injectProductElement([
|
|
145
|
-
{ containerId: 'dynamic-product', identifier: selectedProductId }
|
|
146
|
-
]);
|
|
147
|
-
});
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
---
|
|
151
|
-
|
|
152
|
-
## Actions
|
|
153
|
-
|
|
154
|
-
Control and query product state programmatically.
|
|
155
|
-
|
|
156
|
-
### Get Product Details
|
|
157
|
-
|
|
158
|
-
Retrieve the current state of a displayed product:
|
|
159
|
-
|
|
160
|
-
```javascript
|
|
161
|
-
const details = window.elements.actions.product.getDetails('00619947000020');
|
|
162
|
-
|
|
163
|
-
// Returns product data including:
|
|
164
|
-
// - name, brand, category
|
|
165
|
-
// - selectedSizeId, selectedFulfillmentType
|
|
166
|
-
// - availability status
|
|
167
|
-
// - pricing information
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
---
|
|
171
|
-
|
|
172
|
-
## Events
|
|
173
|
-
|
|
174
|
-
Listen to product interactions and state changes.
|
|
175
|
-
|
|
176
|
-
### Subscribing to Events
|
|
177
|
-
|
|
178
|
-
```javascript
|
|
179
|
-
window.addEventListener('lce:actions.product_loaded', (event) => {
|
|
180
|
-
const { data, metadata } = event.detail;
|
|
181
|
-
console.log('Product loaded:', data.name);
|
|
182
|
-
});
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
### Available Events
|
|
186
|
-
|
|
187
|
-
| Event | Description | Key Data |
|
|
188
|
-
|-------|-------------|----------|
|
|
189
|
-
| `product_loaded` | Product data fetched and displayed | Full product details |
|
|
190
|
-
| `product_add_to_cart` | Customer added product to cart | identifier, fulfillmentId, quantity |
|
|
191
|
-
| `product_quantity_increase` | Quantity increased | identifier, quantity, previousQuantity |
|
|
192
|
-
| `product_quantity_decrease` | Quantity decreased | identifier, quantity, previousQuantity |
|
|
193
|
-
| `product_size_changed` | Size selection changed | identifier, selectedSizeId, previousSizeId |
|
|
194
|
-
| `product_fulfillment_type_changed` | Shipping/on-demand changed | identifier, selectedFulfillmentType |
|
|
195
|
-
| `product_fulfillment_changed` | Retailer selection changed | identifier, selectedFulfillmentId |
|
|
196
|
-
|
|
197
|
-
### Example: Track Add to Cart
|
|
198
|
-
|
|
199
|
-
```javascript
|
|
200
|
-
window.addEventListener('lce:actions.product_add_to_cart', (event) => {
|
|
201
|
-
const { identifier, quantity, fulfillmentId } = event.detail.data;
|
|
202
|
-
|
|
203
|
-
// Send to analytics
|
|
204
|
-
analytics.track('Product Added', {
|
|
205
|
-
productId: identifier,
|
|
206
|
-
quantity: quantity,
|
|
207
|
-
fulfillment: fulfillmentId
|
|
208
|
-
});
|
|
209
|
-
});
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
---
|
|
213
|
-
|
|
214
|
-
## Customization
|
|
215
|
-
|
|
216
|
-
Style product components through the theme configuration.
|
|
217
|
-
|
|
218
|
-
### Basic Theming
|
|
219
|
-
|
|
220
|
-
```javascript
|
|
221
|
-
const client = await Elements('YOUR_API_KEY', {
|
|
222
|
-
customTheme: {
|
|
223
|
-
global: {
|
|
224
|
-
theme: {
|
|
225
|
-
primaryColor: '#007bff',
|
|
226
|
-
buttonCornerRadius: '8px'
|
|
227
|
-
}
|
|
228
|
-
},
|
|
229
|
-
product: {
|
|
230
|
-
// Product-specific theme options
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
});
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
### Product Theme Options
|
|
237
|
-
|
|
238
|
-
See [theming.md](./theming.md) for the complete list of product theme options including:
|
|
239
|
-
- Layout configuration
|
|
240
|
-
- Color overrides
|
|
241
|
-
- Typography settings
|
|
242
|
-
- Spacing and sizing
|
|
243
|
-
|
|
244
|
-
---
|
|
245
|
-
|
|
246
|
-
## See Also
|
|
247
|
-
|
|
248
|
-
- [Actions Reference](./actions.md) - All available actions
|
|
249
|
-
- [Events Reference](./events.md) - All available events
|
|
250
|
-
- [Theming Guide](./theming.md) - Customization options
|
package/docs/proxy.md
DELETED
|
@@ -1,228 +0,0 @@
|
|
|
1
|
-
# Proxy Configuration Guide
|
|
2
|
-
|
|
3
|
-
Configure the LiquidCommerce Elements SDK to route API requests through your own server to avoid ad blockers.
|
|
4
|
-
|
|
5
|
-
## Quick Setup
|
|
6
|
-
|
|
7
|
-
### 1. Configure the SDK
|
|
8
|
-
|
|
9
|
-
```typescript
|
|
10
|
-
const elements = await Elements('your-api-key', {
|
|
11
|
-
env: 'production',
|
|
12
|
-
proxy: {
|
|
13
|
-
baseUrl: 'https://yourdomain.com/api/liquidcommerce'
|
|
14
|
-
}
|
|
15
|
-
});
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
### 2. How It Works
|
|
19
|
-
|
|
20
|
-
```
|
|
21
|
-
Without Proxy: Your App → LiquidCommerce API
|
|
22
|
-
With Proxy: Your App → Your Server → LiquidCommerce API
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
The SDK automatically:
|
|
26
|
-
- Changes API calls from `https://elements.liquidcommerce.us/api/*` to `https://yourdomain.com/api/liquidcommerce/api/*`
|
|
27
|
-
- Adds `X-Liquid-Proxy-Target` header with the original LiquidCommerce URL
|
|
28
|
-
- Sends all required LiquidCommerce headers that your proxy must forward
|
|
29
|
-
|
|
30
|
-
## Required Headers
|
|
31
|
-
|
|
32
|
-
The SDK sends these headers that **must be forwarded** to LiquidCommerce:
|
|
33
|
-
|
|
34
|
-
### Authentication Headers
|
|
35
|
-
- `X-Liquid-Api-Key` - Your LiquidCommerce API key
|
|
36
|
-
- `X-Liquid-Api-Env` - Environment (staging, production, development)
|
|
37
|
-
- `Authorization` - Bearer token (added automatically after authentication)
|
|
38
|
-
|
|
39
|
-
### Tracking Headers
|
|
40
|
-
- `X-Liquid-Api-Sdk` - Source URL (usually `window.location.href`)
|
|
41
|
-
- `X-Liquid-Sdk-Version` - SDK version for debugging
|
|
42
|
-
- `X-Liquid-Proxy` - Always `true` when using a proxy
|
|
43
|
-
|
|
44
|
-
### Proxy Headers
|
|
45
|
-
- `X-Liquid-Proxy-Target` - Original LiquidCommerce API URL to forward to
|
|
46
|
-
- `Content-Type` - Always `application/json`
|
|
47
|
-
|
|
48
|
-
### Your Custom Headers (optional)
|
|
49
|
-
- Any headers you add in `proxy.headers` config
|
|
50
|
-
|
|
51
|
-
## Next.js Implementation
|
|
52
|
-
|
|
53
|
-
### API Route: `pages/api/liquidcommerce/[...path].js`
|
|
54
|
-
|
|
55
|
-
```javascript
|
|
56
|
-
export default async function handler(req, res) {
|
|
57
|
-
// Get the API path from the dynamic route
|
|
58
|
-
const { path } = req.query;
|
|
59
|
-
const apiPath = Array.isArray(path) ? path.join('/') : path;
|
|
60
|
-
|
|
61
|
-
// Get target URL from SDK header
|
|
62
|
-
const targetUrl = req.headers['x-liquid-proxy-target'];
|
|
63
|
-
|
|
64
|
-
if (!targetUrl) {
|
|
65
|
-
return res.status(400).json({ error: 'Missing target URL' });
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// Security: Validate target URL
|
|
69
|
-
const allowedTargets = [
|
|
70
|
-
'https://elements.liquidcommerce.us',
|
|
71
|
-
'https://staging-elements.liquidcommerce.us'
|
|
72
|
-
];
|
|
73
|
-
|
|
74
|
-
if (!allowedTargets.includes(targetUrl)) {
|
|
75
|
-
return res.status(400).json({ error: 'Invalid target URL' });
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
try {
|
|
79
|
-
// Forward the request to LiquidCommerce with ALL required headers
|
|
80
|
-
const response = await fetch(`${targetUrl}/api/${apiPath}`, {
|
|
81
|
-
method: req.method,
|
|
82
|
-
headers: {
|
|
83
|
-
// Required LiquidCommerce headers
|
|
84
|
-
'Content-Type': 'application/json',
|
|
85
|
-
'X-Liquid-Api-Key': req.headers['x-liquid-api-key'],
|
|
86
|
-
'X-Liquid-Api-Env': req.headers['x-liquid-api-env'],
|
|
87
|
-
'X-Liquid-Api-Sdk': req.headers['x-liquid-api-sdk'],
|
|
88
|
-
'X-Liquid-Sdk-Version': req.headers['x-liquid-sdk-version'],
|
|
89
|
-
'X-Liquid-Proxy': req.headers['x-liquid-proxy'],
|
|
90
|
-
'Authorization': req.headers['authorization'],
|
|
91
|
-
// Don't forward the proxy target header to LiquidCommerce
|
|
92
|
-
// 'X-Liquid-Proxy-Target': NOT forwarded
|
|
93
|
-
},
|
|
94
|
-
body: req.method !== 'GET' ? JSON.stringify(req.body) : undefined,
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
const data = await response.json();
|
|
98
|
-
res.status(response.status).json(data);
|
|
99
|
-
|
|
100
|
-
} catch (error) {
|
|
101
|
-
console.error('Proxy error:', error);
|
|
102
|
-
res.status(500).json({ error: 'Proxy error' });
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
### App Router: `app/api/liquidcommerce/[...path]/route.js`
|
|
108
|
-
|
|
109
|
-
```javascript
|
|
110
|
-
export async function GET(request, { params }) {
|
|
111
|
-
return handleRequest(request, params, 'GET');
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
export async function POST(request, { params }) {
|
|
115
|
-
return handleRequest(request, params, 'POST');
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
export async function PUT(request, { params }) {
|
|
119
|
-
return handleRequest(request, params, 'PUT');
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
async function handleRequest(request, params, method) {
|
|
123
|
-
const apiPath = params.path.join('/');
|
|
124
|
-
const targetUrl = request.headers.get('x-liquid-proxy-target');
|
|
125
|
-
|
|
126
|
-
if (!targetUrl) {
|
|
127
|
-
return Response.json({ error: 'Missing target URL' }, { status: 400 });
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// Security check
|
|
131
|
-
const allowedTargets = [
|
|
132
|
-
'https://elements.liquidcommerce.us',
|
|
133
|
-
'https://staging-elements.liquidcommerce.us'
|
|
134
|
-
];
|
|
135
|
-
|
|
136
|
-
if (!allowedTargets.includes(targetUrl)) {
|
|
137
|
-
return Response.json({ error: 'Invalid target URL' }, { status: 400 });
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
try {
|
|
141
|
-
const body = method !== 'GET' ? await request.json() : undefined;
|
|
142
|
-
|
|
143
|
-
const response = await fetch(`${targetUrl}/api/${apiPath}`, {
|
|
144
|
-
method,
|
|
145
|
-
headers: {
|
|
146
|
-
// Required LiquidCommerce headers
|
|
147
|
-
'Content-Type': 'application/json',
|
|
148
|
-
'X-Liquid-Api-Key': request.headers.get('x-liquid-api-key'),
|
|
149
|
-
'X-Liquid-Api-Env': request.headers.get('x-liquid-api-env'),
|
|
150
|
-
'X-Liquid-Api-Sdk': request.headers.get('x-liquid-api-sdk'),
|
|
151
|
-
'X-Liquid-Sdk-Version': request.headers.get('x-liquid-sdk-version'),
|
|
152
|
-
'Authorization': request.headers.get('authorization'),
|
|
153
|
-
// Don't forward the proxy target header to LiquidCommerce
|
|
154
|
-
// 'X-Liquid-Proxy-Target': NOT forwarded
|
|
155
|
-
},
|
|
156
|
-
body: body ? JSON.stringify(body) : undefined,
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
const data = await response.json();
|
|
160
|
-
return Response.json(data, { status: response.status });
|
|
161
|
-
|
|
162
|
-
} catch (error) {
|
|
163
|
-
console.error('Proxy error:', error);
|
|
164
|
-
return Response.json({ error: 'Proxy error' }, { status: 500 });
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
## Testing
|
|
170
|
-
|
|
171
|
-
### 1. Test the proxy endpoint directly:
|
|
172
|
-
|
|
173
|
-
```bash
|
|
174
|
-
curl -X GET "https://yourdomain.com/api/liquidcommerce/configs" \
|
|
175
|
-
-H "Content-Type: application/json" \
|
|
176
|
-
-H "X-Liquid-Proxy-Target: https://staging-elements.liquidcommerce.us" \
|
|
177
|
-
-H "X-Liquid-Api-Key: your-api-key" \
|
|
178
|
-
-H "X-Liquid-Api-Env: staging" \
|
|
179
|
-
-H "X-Liquid-Api-Sdk: https://yoursite.com" \
|
|
180
|
-
-H "X-Liquid-Sdk-Version: 1.0.0"
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
### 2. Use the SDK with proxy:
|
|
184
|
-
|
|
185
|
-
```javascript
|
|
186
|
-
// This will automatically use your proxy
|
|
187
|
-
const elements = await Elements('your-api-key', {
|
|
188
|
-
env: 'staging',
|
|
189
|
-
proxy: {
|
|
190
|
-
baseUrl: 'https://yourdomain.com/api/liquidcommerce'
|
|
191
|
-
}
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
await elements.prepare(); // Uses proxy for all API calls
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
## Security
|
|
198
|
-
|
|
199
|
-
1. **Validate target URLs** - Only allow known LiquidCommerce domains
|
|
200
|
-
2. **Forward required headers only** - Forward the headers listed above, exclude internal ones
|
|
201
|
-
3. **Don't forward `X-Liquid-Proxy-Target`** - This is for your proxy only, not LiquidCommerce
|
|
202
|
-
4. **Add rate limiting** if needed
|
|
203
|
-
5. **Log requests** for monitoring
|
|
204
|
-
|
|
205
|
-
## Important Notes
|
|
206
|
-
|
|
207
|
-
- **All SDK headers must be forwarded** - Missing headers will cause authentication failures
|
|
208
|
-
- **`Authorization` header is added automatically** - After the SDK authenticates with your API key
|
|
209
|
-
- **`X-Liquid-Proxy-Target` stays with your proxy** - Don't send this to LiquidCommerce
|
|
210
|
-
- **Content-Type must be `application/json`** - Required for all API requests
|
|
211
|
-
|
|
212
|
-
## Benefits
|
|
213
|
-
|
|
214
|
-
- ✅ **Bypass ad blockers** - Requests come from your domain
|
|
215
|
-
- ✅ **Control requests** - Monitor and modify API calls
|
|
216
|
-
- ✅ **Add authentication** - Include your own auth headers
|
|
217
|
-
- ✅ **Zero client changes** - Transparent to the SDK
|
|
218
|
-
|
|
219
|
-
## Configuration Options
|
|
220
|
-
|
|
221
|
-
```typescript
|
|
222
|
-
proxy: {
|
|
223
|
-
baseUrl: 'https://yourdomain.com/api/liquidcommerce', // Required: Full proxy endpoint URL
|
|
224
|
-
headers: { // Optional: Custom headers
|
|
225
|
-
'X-Custom-Header': 'value'
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
```
|