@liquidcommerce/elements-sdk 2.7.14 → 2.7.15
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.checkout.esm.js +7244 -7174
- package/dist/index.esm.js +11631 -11448
- package/dist/types/auto-initialize/shared-utils.d.ts +3 -0
- package/dist/types/clients/helpers.d.ts +0 -1
- package/dist/types/interfaces/configs/product-list.interface.d.ts +3 -1
- package/dist/types/interfaces/configs/product.interface.d.ts +2 -2
- package/dist/types/interfaces/injection.interface.d.ts +2 -1
- package/dist/types/modules/product-list/components/product-list-card.component.d.ts +7 -1
- package/dist/types/modules/product-list/product-list-query-params.utils.d.ts +3 -0
- package/dist/types/modules/product-list/product-list.commands.d.ts +1 -1
- package/dist/types/modules/product-list/product-list.component.d.ts +2 -1
- package/docs/v1/api/injection-methods.md +30 -3
- package/docs/v1/api/typescript-types.md +17 -1
- package/docs/v1/examples/advanced-patterns.md +1 -1
- package/docs/v1/guides/product-list-component.md +134 -9
- package/package.json +4 -4
|
@@ -28,11 +28,14 @@ export declare const SHARED_ATTR: {
|
|
|
28
28
|
readonly JSON_SCRIPT: {
|
|
29
29
|
readonly DEVELOPMENT: "data-liquid-commerce-elements-development";
|
|
30
30
|
readonly CUSTOM_THEME: "data-liquid-commerce-elements-custom-theme";
|
|
31
|
+
readonly PRODUCT_URLS: "data-liquid-commerce-elements-product-urls";
|
|
31
32
|
};
|
|
32
33
|
};
|
|
34
|
+
export type ProductUrlsConfig = Record<string, Record<string, string>>;
|
|
33
35
|
export declare function startsWithLcePrefix(value: string | null): boolean;
|
|
34
36
|
export declare function getDevelopmentConfigs(): ILiquidCommerceElementsDevelopmentConfig | undefined;
|
|
35
37
|
export declare function getCustomThemeConfig(): IClientCustomThemeConfig | undefined;
|
|
38
|
+
export declare function getProductUrlsConfig(): ProductUrlsConfig | undefined;
|
|
36
39
|
export declare function triggerAutoInit(initFunction: () => Promise<void>, errorPrefix: string): void;
|
|
37
40
|
export declare function setupCheckout(script: HTMLScriptElement, injectFn: (params: IInjectCheckoutParams) => Promise<IInjectedComponent | null>, exitCheckoutFn: () => void, options: {
|
|
38
41
|
errorPrefix: string;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { type ComponentType } from '@/enums';
|
|
2
|
-
export declare function applyConfigDefaults<T extends Record<string, any>>(data: T): T;
|
|
3
2
|
export declare function normalizeProductListLists<T extends Record<string, any>>(data: T): T;
|
|
4
3
|
export declare function deepMergeConfigs<T extends Record<string, any>>(target: T, source: Partial<T>, currentPath?: string): T;
|
|
5
4
|
export declare const layoutFieldToComponentTypes: Map<string, ComponentType[]>;
|
|
@@ -3,6 +3,7 @@ import type { ProductListFilterType } from '@/interfaces/injection.interface';
|
|
|
3
3
|
export type PLCPresentationModeType = 'drawer' | 'modal';
|
|
4
4
|
export type PLCListType = 'curated' | 'dynamic';
|
|
5
5
|
export type PLCCardStyle = 'card' | 'ghost';
|
|
6
|
+
export type PLCProductUrl = string | Record<string, string>;
|
|
6
7
|
export interface IPLCProductCard {
|
|
7
8
|
style: PLCCardStyle;
|
|
8
9
|
cornerRadius: string;
|
|
@@ -16,6 +17,8 @@ export interface IPLCProductCard {
|
|
|
16
17
|
showQuantityCounter: boolean;
|
|
17
18
|
enablePreCart: boolean;
|
|
18
19
|
showCollectionTags: boolean;
|
|
20
|
+
productUrl: PLCProductUrl | null;
|
|
21
|
+
noAvailabilityText: string;
|
|
19
22
|
}
|
|
20
23
|
export interface IPLCList {
|
|
21
24
|
type: PLCListType;
|
|
@@ -27,7 +30,6 @@ export interface IPLCList {
|
|
|
27
30
|
availableFilters: ProductListFilterType[];
|
|
28
31
|
rows: number;
|
|
29
32
|
columns: number;
|
|
30
|
-
productUrl: string | null;
|
|
31
33
|
}
|
|
32
34
|
export interface IProductListLayout {
|
|
33
35
|
lists: IPLCList[];
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type { DeepPartial } from '@/interfaces/config.interface';
|
|
2
2
|
export type FulfillmentDisplayType = 'carousel' | 'popup';
|
|
3
|
-
export type
|
|
3
|
+
export type DescriptionPositionType = 'above' | 'below';
|
|
4
4
|
export interface IProductLayout {
|
|
5
5
|
showImages: boolean;
|
|
6
6
|
showOnlyMainImage: boolean;
|
|
7
7
|
showTitle: boolean;
|
|
8
8
|
showDescription: boolean;
|
|
9
|
-
descriptionPosition:
|
|
9
|
+
descriptionPosition: DescriptionPositionType;
|
|
10
10
|
showQuantityCounter: boolean;
|
|
11
11
|
showOffHours: boolean;
|
|
12
12
|
quantityCounterStyle: 'outlined' | 'ghost';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { PRODUCT_LIST_FILTER_TYPES } from '@/constants';
|
|
2
2
|
import type { ComponentType } from '@/enums';
|
|
3
|
+
import type { PLCProductUrl } from '@/interfaces/configs/product-list.interface';
|
|
3
4
|
import type { IAddressOptions } from '@/modules/address/address.interface';
|
|
4
5
|
export interface IInjectProductElement {
|
|
5
6
|
containerId: string;
|
|
@@ -12,7 +13,7 @@ export interface IInjectProductListParams {
|
|
|
12
13
|
rows?: number;
|
|
13
14
|
columns?: number;
|
|
14
15
|
filters?: ProductListFilterType[];
|
|
15
|
-
productUrl?:
|
|
16
|
+
productUrl?: PLCProductUrl;
|
|
16
17
|
}
|
|
17
18
|
export interface IInjectProductListSearchParams {
|
|
18
19
|
containerId: string;
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import { BaseComponent, type IOnStoreChanged } from '@/core/base-component.service';
|
|
2
2
|
import type { IProductListComponent } from '@/interfaces/configs';
|
|
3
|
+
import type { PLCProductUrl } from '@/interfaces/configs/product-list.interface';
|
|
3
4
|
export interface IProductListCardParams {
|
|
4
5
|
slug: string;
|
|
5
6
|
productId: string;
|
|
6
|
-
productUrl?:
|
|
7
|
+
productUrl?: PLCProductUrl;
|
|
7
8
|
}
|
|
8
9
|
export declare class ProductListCardComponent extends BaseComponent<IProductListCardParams, IProductListComponent> {
|
|
9
10
|
private imageElement;
|
|
10
11
|
private priceElement;
|
|
11
12
|
private personalizeElement;
|
|
12
13
|
private fulfillmentTextElement;
|
|
14
|
+
private fulfillmentWrapperElement;
|
|
13
15
|
private addToCartButton;
|
|
16
|
+
private noAvailabilityElement;
|
|
14
17
|
private previousSelectedSizeId;
|
|
15
18
|
private previousSelectedFulfillmentId;
|
|
16
19
|
constructor();
|
|
@@ -27,10 +30,13 @@ export declare class ProductListCardComponent extends BaseComponent<IProductList
|
|
|
27
30
|
private updateImage;
|
|
28
31
|
private updatePersonalizeVisibility;
|
|
29
32
|
private updateAddToCartButton;
|
|
33
|
+
private syncFulfillmentWrapperContent;
|
|
30
34
|
private generateProductUrl;
|
|
31
35
|
private createImageSection;
|
|
32
36
|
private createContentSection;
|
|
37
|
+
private createNoAvailabilityMessage;
|
|
33
38
|
private createFulfillmentSectionWrapper;
|
|
39
|
+
private createDeliveryOptionsButton;
|
|
34
40
|
private createFulfillmentTextSection;
|
|
35
41
|
private createAddToCartSection;
|
|
36
42
|
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { ProductListFilterType } from '@/interfaces/injection.interface';
|
|
2
|
+
import type { IProductListFilters } from './product-list.interface';
|
|
3
|
+
export declare function parseQueryParamsToFilters(configuredFilters: ProductListFilterType[], search?: string): IProductListFilters | null;
|
|
@@ -9,7 +9,7 @@ export declare class ProductListCommands extends BaseCommand {
|
|
|
9
9
|
private readonly cartCommands;
|
|
10
10
|
constructor();
|
|
11
11
|
static getInstance(): ProductListCommands;
|
|
12
|
-
initializeListStore(slug: string): void;
|
|
12
|
+
initializeListStore(slug: string, configuredFilters?: ProductListFilterType[]): void;
|
|
13
13
|
updateSearchTerm(slug: string, searchTerm: string): void;
|
|
14
14
|
setLoading(slug: string, isLoading: boolean): void;
|
|
15
15
|
rerenderProductLists(): void;
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { BaseComponent, type IOnStoreChanged } from '@/core/base-component.service';
|
|
2
2
|
import type { IProductListComponent } from '@/interfaces/configs';
|
|
3
|
+
import type { PLCProductUrl } from '@/interfaces/configs/product-list.interface';
|
|
3
4
|
import type { ProductListFilterType } from '@/interfaces/injection.interface';
|
|
4
5
|
export interface IProductListComponentParams {
|
|
5
6
|
slug: string;
|
|
6
7
|
rows: number;
|
|
7
8
|
columns: number;
|
|
8
9
|
filters: ProductListFilterType[];
|
|
9
|
-
productUrl?:
|
|
10
|
+
productUrl?: PLCProductUrl;
|
|
10
11
|
}
|
|
11
12
|
export declare class ProductListComponent extends BaseComponent<IProductListComponentParams, IProductListComponent> {
|
|
12
13
|
private products;
|
|
@@ -130,11 +130,15 @@ interface IInjectProductListParams {
|
|
|
130
130
|
rows?: number; // Default: 3
|
|
131
131
|
columns?: number; // Default: 4
|
|
132
132
|
filters?: ProductListFilterType[];
|
|
133
|
-
productUrl?:
|
|
133
|
+
productUrl?: PLCProductUrl; // string template OR Record<identifier, url> map
|
|
134
134
|
}
|
|
135
|
+
|
|
136
|
+
// String template: replace {upc} or {grouping} per product.
|
|
137
|
+
// Map: keys are product identifiers (UPC or salsifyGrouping ID); UPC checked first.
|
|
138
|
+
type PLCProductUrl = string | Record<string, string>;
|
|
135
139
|
```
|
|
136
140
|
|
|
137
|
-
### Example
|
|
141
|
+
### Example — string template
|
|
138
142
|
|
|
139
143
|
```javascript
|
|
140
144
|
await client.injectProductList({
|
|
@@ -143,7 +147,30 @@ await client.injectProductList({
|
|
|
143
147
|
rows: 4,
|
|
144
148
|
columns: 3,
|
|
145
149
|
filters: ['price', 'brands', 'categories'],
|
|
146
|
-
productUrl: '/product/{
|
|
150
|
+
productUrl: '/product/{grouping}'
|
|
151
|
+
});
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
> The `filters` array also acts as the whitelist for **URL query param filtering** —
|
|
155
|
+
> the product list reads `?brands=...&price=...` etc. from `window.location.search`
|
|
156
|
+
> on first mount and applies them. See
|
|
157
|
+
> [URL Query Param Filters](../guides/product-list-component.md#url-query-param-filters).
|
|
158
|
+
|
|
159
|
+
### Example — URL map (partner-owned dedicated PDPs)
|
|
160
|
+
|
|
161
|
+
Use this form when each product has a hand-curated URL that can't be derived
|
|
162
|
+
from a single `{upc}` or `{grouping}` token. See the
|
|
163
|
+
[Product List guide](../guides/product-list-component.md#product-url-map) for
|
|
164
|
+
the equivalent declarative `<script type="application/json">` pattern.
|
|
165
|
+
|
|
166
|
+
```javascript
|
|
167
|
+
await client.injectProductList({
|
|
168
|
+
containerId: 'products',
|
|
169
|
+
slug: 'best-sellers',
|
|
170
|
+
productUrl: {
|
|
171
|
+
'GROUPING-33277': '/wines/macallan-12-special-edition',
|
|
172
|
+
'00832889005513': '/spirits/cabernet-2018-club-only',
|
|
173
|
+
},
|
|
147
174
|
});
|
|
148
175
|
```
|
|
149
176
|
|
|
@@ -190,10 +190,26 @@ interface IInjectProductListParams {
|
|
|
190
190
|
rows?: number;
|
|
191
191
|
columns?: number;
|
|
192
192
|
filters?: ProductListFilterType[];
|
|
193
|
-
productUrl?:
|
|
193
|
+
productUrl?: PLCProductUrl;
|
|
194
194
|
}
|
|
195
195
|
```
|
|
196
196
|
|
|
197
|
+
### PLCProductUrl
|
|
198
|
+
|
|
199
|
+
```typescript
|
|
200
|
+
/**
|
|
201
|
+
* Product card link configuration.
|
|
202
|
+
*
|
|
203
|
+
* - String: template with `{upc}` (selected size's UPC) or `{grouping}`
|
|
204
|
+
* (product's salsifyGrouping ID). Replaced per product card.
|
|
205
|
+
* - Map: keyed by product identifier (UPC or salsifyGrouping ID — same
|
|
206
|
+
* identifier types accepted by `injectProductElement`). The card looks up
|
|
207
|
+
* UPC first, then grouping ID. Use this when partner PDPs have
|
|
208
|
+
* hand-curated URLs that aren't derivable from a single token.
|
|
209
|
+
*/
|
|
210
|
+
type PLCProductUrl = string | Record<string, string>;
|
|
211
|
+
```
|
|
212
|
+
|
|
197
213
|
### IInjectProductListSearchParams
|
|
198
214
|
|
|
199
215
|
```typescript
|
|
@@ -33,7 +33,7 @@ Use data attributes to configure the product list:
|
|
|
33
33
|
data-rows="3"
|
|
34
34
|
data-columns="4"
|
|
35
35
|
data-filters="price,brands,categories"
|
|
36
|
-
data-product-url="/product/{
|
|
36
|
+
data-product-url="/product/{grouping}"
|
|
37
37
|
></div>
|
|
38
38
|
```
|
|
39
39
|
|
|
@@ -44,7 +44,13 @@ Use data attributes to configure the product list:
|
|
|
44
44
|
- `data-filters`: Comma-separated filter types
|
|
45
45
|
- `data-product-url`: URL pattern for product detail pages (optional)
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
`data-product-url` accepts a string template with one of two placeholders:
|
|
48
|
+
- `{grouping}` — replaced with the product's salsifyGrouping ID
|
|
49
|
+
- `{upc}` — replaced with the selected size's UPC
|
|
50
|
+
|
|
51
|
+
If your PDP URLs aren't derivable from a single placeholder (e.g. each
|
|
52
|
+
product has a hand-curated marketing slug), use the
|
|
53
|
+
[Product URL Map](#product-url-map) instead.
|
|
48
54
|
|
|
49
55
|
### With Search and Filters
|
|
50
56
|
|
|
@@ -62,7 +68,7 @@ Separate containers for search and filters:
|
|
|
62
68
|
data-liquid-commerce-elements-products-list="my-collection-slug"
|
|
63
69
|
data-rows="4"
|
|
64
70
|
data-columns="3"
|
|
65
|
-
data-product-url="/products/{
|
|
71
|
+
data-product-url="/products/{grouping}"
|
|
66
72
|
></div>
|
|
67
73
|
```
|
|
68
74
|
|
|
@@ -80,7 +86,7 @@ await client.injectProductList({
|
|
|
80
86
|
rows: 3,
|
|
81
87
|
columns: 4,
|
|
82
88
|
filters: ['price', 'brands', 'categories', 'fulfillment'],
|
|
83
|
-
productUrl: '/product/{
|
|
89
|
+
productUrl: '/product/{grouping}'
|
|
84
90
|
});
|
|
85
91
|
|
|
86
92
|
// Inject search (optional)
|
|
@@ -122,6 +128,55 @@ The following filter type values can be used in the `filters` array:
|
|
|
122
128
|
filters: ['price', 'brands', 'categories', 'fulfillment', 'sizes']
|
|
123
129
|
```
|
|
124
130
|
|
|
131
|
+
## URL Query Param Filters
|
|
132
|
+
|
|
133
|
+
The product list auto-applies filters from the page URL on first load. Useful for category landing pages, "shop the look" links, marketing emails, or any flow where you want to deep-link into a pre-filtered list.
|
|
134
|
+
|
|
135
|
+
### Whitelist
|
|
136
|
+
|
|
137
|
+
Only filter keys that are configured for the list are honored — anything else in the URL is silently ignored. The whitelist resolves in this priority order:
|
|
138
|
+
|
|
139
|
+
1. `data-filters` on `<div data-liquid-commerce-elements-products-list>` (use this when the page does **not** mount a filters UI but you still want URL filtering — e.g. a curated category page).
|
|
140
|
+
2. `data-filters` on the matching `<... -products-list-filters>` container (the common case when a filters panel is mounted).
|
|
141
|
+
3. `availableFilters` from the theme config for the list slug.
|
|
142
|
+
4. `filters` array passed to `injectProductList(...)` programmatically.
|
|
143
|
+
|
|
144
|
+
### Supported formats
|
|
145
|
+
|
|
146
|
+
| Filter | URL format | Example |
|
|
147
|
+
| --- | --- | --- |
|
|
148
|
+
| Multi-value (`brands`, `categories`, `flavor`, `region`, `variety`, `vintage`, `country`, `appellation`, `materials`, `sizes`) | Comma-separated **or** repeated keys | `?brands=Bacardi,Glenlivet` or `?brands=Bacardi&brands=Glenlivet` |
|
|
149
|
+
| `fulfillment` | Single value: `all`, `shipping`, or `onDemand` | `?fulfillment=shipping` |
|
|
150
|
+
| `engraving` | `true` or `false` | `?engraving=true` |
|
|
151
|
+
| `price` | `min-max` range; `min-` or `-max` are accepted | `?price=20-150`, `?price=20-`, `?price=-150` |
|
|
152
|
+
|
|
153
|
+
Invalid values are dropped (e.g. `?fulfillment=garbage`, `?price=abc` — no error, the filter just isn't applied). Combining params is supported:
|
|
154
|
+
|
|
155
|
+
```
|
|
156
|
+
https://yoursite.com/best-sellers?brands=Bacardi&categories=Wine&price=20-150&fulfillment=shipping
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Behavior
|
|
160
|
+
|
|
161
|
+
- URL params win over any state persisted from a previous session.
|
|
162
|
+
- Once the list mounts, the filters panel (if present) reflects the seeded values, and the initial product fetch is filtered.
|
|
163
|
+
- Subsequent in-page interactions (toggling filters, scrolling, etc.) do not write back to the URL — the URL is read-only at load time.
|
|
164
|
+
|
|
165
|
+
### Standalone use (no filters component)
|
|
166
|
+
|
|
167
|
+
URL filtering works without injecting a filters panel. Declare the whitelist on the products-list container itself:
|
|
168
|
+
|
|
169
|
+
```html
|
|
170
|
+
<div
|
|
171
|
+
data-liquid-commerce-elements-products-list="curated-page"
|
|
172
|
+
data-filters="price,brands,categories"
|
|
173
|
+
data-rows="4"
|
|
174
|
+
data-columns="4"
|
|
175
|
+
></div>
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Now `https://yoursite.com/curated-page?brands=Bacardi&price=20-150` filters the list on load even though no filters UI is present.
|
|
179
|
+
|
|
125
180
|
## Search Functionality
|
|
126
181
|
|
|
127
182
|
### Search Box
|
|
@@ -213,7 +268,7 @@ Each product card shows:
|
|
|
213
268
|
|
|
214
269
|
### Card Interaction
|
|
215
270
|
|
|
216
|
-
**Click on card:** Navigate to product detail page (if `productUrl` configured)
|
|
271
|
+
**Click on card:** Navigate to product detail page (if `productUrl` configured — see [Product URL Map](#product-url-map) for partner-owned PDP URLs that aren't derivable from a token).
|
|
217
272
|
|
|
218
273
|
**Quick Add:** Add product to cart directly from list view (if enabled)
|
|
219
274
|
|
|
@@ -298,7 +353,7 @@ See [Configuration Reference](../api/configuration.md#product-list-theme) for th
|
|
|
298
353
|
data-liquid-commerce-elements-products-list="whiskey-collection"
|
|
299
354
|
data-rows="4"
|
|
300
355
|
data-columns="3"
|
|
301
|
-
data-product-url="/whiskey/{
|
|
356
|
+
data-product-url="/whiskey/{grouping}"
|
|
302
357
|
></div>
|
|
303
358
|
</main>
|
|
304
359
|
</div>
|
|
@@ -339,13 +394,13 @@ const productType = getProductTypeFromData();
|
|
|
339
394
|
let urlPattern;
|
|
340
395
|
switch (productType) {
|
|
341
396
|
case 'whiskey':
|
|
342
|
-
urlPattern = '/spirits/whiskey/{
|
|
397
|
+
urlPattern = '/spirits/whiskey/{grouping}';
|
|
343
398
|
break;
|
|
344
399
|
case 'wine':
|
|
345
|
-
urlPattern = '/wine/{
|
|
400
|
+
urlPattern = '/wine/{grouping}';
|
|
346
401
|
break;
|
|
347
402
|
default:
|
|
348
|
-
urlPattern = '/products/{
|
|
403
|
+
urlPattern = '/products/{grouping}';
|
|
349
404
|
}
|
|
350
405
|
|
|
351
406
|
await client.injectProductList({
|
|
@@ -357,6 +412,76 @@ await client.injectProductList({
|
|
|
357
412
|
});
|
|
358
413
|
```
|
|
359
414
|
|
|
415
|
+
### Product URL Map
|
|
416
|
+
|
|
417
|
+
For partners whose PDPs have hand-curated URLs that aren't derivable from a
|
|
418
|
+
single placeholder (e.g. dedicated marketing pages, Shopify handles, WordPress
|
|
419
|
+
slugs), pass a **map** instead of a string template. Keys are product
|
|
420
|
+
identifiers — either a UPC or a salsifyGrouping ID, the same identifier types
|
|
421
|
+
accepted by `injectProductElement`. The card looks up UPC first, then grouping
|
|
422
|
+
ID; products not in the map render without a link.
|
|
423
|
+
|
|
424
|
+
#### Declarative — JSON script tag
|
|
425
|
+
|
|
426
|
+
Drop a single `<script type="application/json">` tag anywhere on the page,
|
|
427
|
+
keyed by list slug → identifier → URL. Generate it server-side from your CMS.
|
|
428
|
+
|
|
429
|
+
```html
|
|
430
|
+
<script data-liquid-commerce-elements-product-urls type="application/json">
|
|
431
|
+
{
|
|
432
|
+
"best-sellers": {
|
|
433
|
+
"GROUPING-33277": "/wines/macallan-12-special-edition",
|
|
434
|
+
"00832889005513": "/spirits/cabernet-2018-club-only"
|
|
435
|
+
},
|
|
436
|
+
"limited-releases": {
|
|
437
|
+
"GROUPING-78941": "/exclusive/pappy-23-allocation"
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
</script>
|
|
441
|
+
|
|
442
|
+
<div data-liquid-commerce-elements-products-list="best-sellers"></div>
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
When both `data-product-url` and a slug entry in this script are present for
|
|
446
|
+
the same list, the **map wins** — it's the more specific intent.
|
|
447
|
+
|
|
448
|
+
##### Shopify Liquid
|
|
449
|
+
|
|
450
|
+
```liquid
|
|
451
|
+
<script data-liquid-commerce-elements-product-urls type="application/json">
|
|
452
|
+
{
|
|
453
|
+
"best-sellers": {
|
|
454
|
+
{% for p in collections.best-sellers.products %}
|
|
455
|
+
"{{ p.metafields.lc.grouping_id }}": "{{ p.url }}"{% unless forloop.last %},{% endunless %}
|
|
456
|
+
{% endfor %}
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
</script>
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
##### WordPress / WooCommerce (PHP)
|
|
463
|
+
|
|
464
|
+
```php
|
|
465
|
+
<script data-liquid-commerce-elements-product-urls type="application/json">
|
|
466
|
+
<?= json_encode(['best-sellers' => $lc_identifier_to_pdp_url_map]) ?>
|
|
467
|
+
</script>
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
#### Programmatic
|
|
471
|
+
|
|
472
|
+
```javascript
|
|
473
|
+
await client.injectProductList({
|
|
474
|
+
containerId: 'products',
|
|
475
|
+
slug: 'best-sellers',
|
|
476
|
+
rows: 3,
|
|
477
|
+
columns: 4,
|
|
478
|
+
productUrl: {
|
|
479
|
+
'GROUPING-33277': '/wines/macallan-12-special-edition',
|
|
480
|
+
'00832889005513': '/spirits/cabernet-2018-club-only',
|
|
481
|
+
},
|
|
482
|
+
});
|
|
483
|
+
```
|
|
484
|
+
|
|
360
485
|
## Events
|
|
361
486
|
|
|
362
487
|
While product list events are primarily internal, you can listen for cart events when users add products:
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "LiquidCommerce Elements SDK",
|
|
4
4
|
"license": "UNLICENSED",
|
|
5
5
|
"author": "LiquidCommerce Team",
|
|
6
|
-
"version": "2.7.
|
|
6
|
+
"version": "2.7.15",
|
|
7
7
|
"homepage": "https://docs.liquidcommerce.co/elements-sdk",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
},
|
|
15
15
|
"module": "./dist/index.esm.js",
|
|
16
16
|
"types": "./dist/types/index.d.ts",
|
|
17
|
-
"packageManager": "pnpm@10.33.
|
|
17
|
+
"packageManager": "pnpm@10.33.4",
|
|
18
18
|
"exports": {
|
|
19
19
|
".": {
|
|
20
20
|
"types": "./dist/types/index.d.ts",
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
"embeddable commerce"
|
|
78
78
|
],
|
|
79
79
|
"devDependencies": {
|
|
80
|
-
"@biomejs/biome": "^2.4.
|
|
80
|
+
"@biomejs/biome": "^2.4.14",
|
|
81
81
|
"@commitlint/cli": "^20.5.3",
|
|
82
82
|
"@commitlint/config-conventional": "^20.5.3",
|
|
83
83
|
"@rollup/plugin-alias": "^6.0.0",
|
|
@@ -97,7 +97,7 @@
|
|
|
97
97
|
"conventional-changelog": "^7.2.0",
|
|
98
98
|
"husky": "^9.1.7",
|
|
99
99
|
"process": "^0.11.10",
|
|
100
|
-
"rollup": "^4.60.
|
|
100
|
+
"rollup": "^4.60.3",
|
|
101
101
|
"rollup-obfuscator": "^4.1.1",
|
|
102
102
|
"rollup-plugin-typescript2": "^0.37.0",
|
|
103
103
|
"semantic-release": "^25.0.3",
|