@dutchiesdk/ecommerce-extensions-sdk 0.16.0 → 0.18.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/README.md
CHANGED
|
@@ -26,11 +26,7 @@ yarn add @dutchie/ecommerce-extensions-sdk
|
|
|
26
26
|
|
|
27
27
|
```tsx
|
|
28
28
|
import React from "react";
|
|
29
|
-
import {
|
|
30
|
-
useDataBridge,
|
|
31
|
-
RemoteBoundaryComponent,
|
|
32
|
-
DataBridgeVersion,
|
|
33
|
-
} from "@dutchie/ecommerce-extensions-sdk";
|
|
29
|
+
import { useDataBridge, RemoteBoundaryComponent, DataBridgeVersion } from "@dutchie/ecommerce-extensions-sdk";
|
|
34
30
|
|
|
35
31
|
const MyExtension: RemoteBoundaryComponent = () => {
|
|
36
32
|
const { dataLoaders, actions, location, user, cart } = useDataBridge();
|
|
@@ -78,10 +74,7 @@ const MyComponent = () => {
|
|
|
78
74
|
A utility hook for handling async data loading with loading states.
|
|
79
75
|
|
|
80
76
|
```tsx
|
|
81
|
-
import {
|
|
82
|
-
useAsyncLoader,
|
|
83
|
-
useDataBridge,
|
|
84
|
-
} from "@dutchie/ecommerce-extensions-sdk";
|
|
77
|
+
import { useAsyncLoader, useDataBridge } from "@dutchie/ecommerce-extensions-sdk";
|
|
85
78
|
|
|
86
79
|
const ProductList = () => {
|
|
87
80
|
const { dataLoaders } = useDataBridge();
|
|
@@ -125,11 +118,7 @@ All extension components that integrate with the Dutchie platform should satisfy
|
|
|
125
118
|
**Example:**
|
|
126
119
|
|
|
127
120
|
```tsx
|
|
128
|
-
import {
|
|
129
|
-
RemoteBoundaryComponent,
|
|
130
|
-
useDataBridge,
|
|
131
|
-
DataBridgeVersion,
|
|
132
|
-
} from "@dutchie/ecommerce-extensions-sdk";
|
|
121
|
+
import { RemoteBoundaryComponent, useDataBridge, DataBridgeVersion } from "@dutchie/ecommerce-extensions-sdk";
|
|
133
122
|
|
|
134
123
|
const MyCustomHeader: RemoteBoundaryComponent = () => {
|
|
135
124
|
const { location, user, actions } = useDataBridge();
|
|
@@ -137,11 +126,7 @@ const MyCustomHeader: RemoteBoundaryComponent = () => {
|
|
|
137
126
|
return (
|
|
138
127
|
<header>
|
|
139
128
|
<h1>{location?.name}</h1>
|
|
140
|
-
{user ?
|
|
141
|
-
<span>Welcome, {user.firstName}!</span>
|
|
142
|
-
) : (
|
|
143
|
-
<button onClick={actions.goToLogin}>Login</button>
|
|
144
|
-
)}
|
|
129
|
+
{user ? <span>Welcome, {user.firstName}!</span> : <button onClick={actions.goToLogin}>Login</button>}
|
|
145
130
|
</header>
|
|
146
131
|
);
|
|
147
132
|
};
|
|
@@ -191,6 +176,231 @@ const currentLocations = await dataLoaders.locations(); // Current context locat
|
|
|
191
176
|
|
|
192
177
|
You can register callback functions that will be triggered by certain events in the Dutchie platform in your extension's `RemoteModuleRegistry` object.
|
|
193
178
|
|
|
179
|
+
## Meta Fields Function
|
|
180
|
+
|
|
181
|
+
### Overview
|
|
182
|
+
|
|
183
|
+
The `getStoreFrontMetaFields` function is the **recommended approach** for generating page metadata (title tags, meta descriptions, Open Graph tags, etc.) in your theme. This function-based approach replaces the `StoreFrontMeta` component pattern.
|
|
184
|
+
|
|
185
|
+
**Why use this approach:**
|
|
186
|
+
|
|
187
|
+
- ✅ **Full data access** - Direct access to data loaders (products, categories, etc.)
|
|
188
|
+
- ✅ **Async support** - Make API calls to fetch data for dynamic meta tags
|
|
189
|
+
- ✅ **Centralized control** - Single function handles all page metadata logic
|
|
190
|
+
- ✅ **Better performance** - Called once per navigation, not re-rendered on state changes
|
|
191
|
+
|
|
192
|
+
> **🚀 Rollout Status:** The Dutchie platform is currently rolling out support for `getStoreFrontMetaFields` via a feature flag. During the transition period:
|
|
193
|
+
>
|
|
194
|
+
> - When the flag is **enabled**: Your `getStoreFrontMetaFields` function will be used (recommended)
|
|
195
|
+
> - When the flag is **disabled**: The legacy `StoreFrontMeta` component will be used
|
|
196
|
+
> - Both implementations can coexist in your theme during migration
|
|
197
|
+
> - The component approach will be deprecated once the rollout is complete
|
|
198
|
+
|
|
199
|
+
> **Note:** When you provide `getStoreFrontMetaFields` and the feature flag is enabled, the `StoreFrontMeta` component will not be used. We recommend implementing the function approach now to prepare for the full migration
|
|
200
|
+
|
|
201
|
+
### Function Signature
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
export type StoreFrontMetaFieldsFunction = (data: CommerceComponentsDataInterface) => MetaFields | Promise<MetaFields>;
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
The function receives the full data bridge interface and can return meta fields synchronously or asynchronously.
|
|
208
|
+
|
|
209
|
+
### Meta Fields Type
|
|
210
|
+
|
|
211
|
+
```typescript
|
|
212
|
+
type MetaFields = {
|
|
213
|
+
title?: string; // Page title
|
|
214
|
+
description?: string; // Meta description
|
|
215
|
+
ogImage?: string; // Open Graph image URL
|
|
216
|
+
canonical?: string; // Canonical URL
|
|
217
|
+
structuredData?: Record<string, any>; // JSON-LD structured data
|
|
218
|
+
customMeta?: Array<{
|
|
219
|
+
// Additional meta tags
|
|
220
|
+
name?: string;
|
|
221
|
+
property?: string;
|
|
222
|
+
content: string;
|
|
223
|
+
}>;
|
|
224
|
+
};
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Implementation
|
|
228
|
+
|
|
229
|
+
Create a file in your theme (e.g., `get-meta-fields.ts`):
|
|
230
|
+
|
|
231
|
+
```typescript
|
|
232
|
+
import { CommerceComponentsDataInterface, MetaFields } from "@dutchiesdk/ecommerce-extensions-sdk";
|
|
233
|
+
|
|
234
|
+
export const getStoreFrontMetaFields = async (data: CommerceComponentsDataInterface): Promise<MetaFields> => {
|
|
235
|
+
const { location, dataLoaders } = data;
|
|
236
|
+
const page = typeof window !== "undefined" ? window.location.pathname : "";
|
|
237
|
+
|
|
238
|
+
// Access data loaders for dynamic content
|
|
239
|
+
const product = await dataLoaders.product();
|
|
240
|
+
const categories = await dataLoaders.categories();
|
|
241
|
+
|
|
242
|
+
// Generate page-specific metadata
|
|
243
|
+
let pageTitle = location?.name || "Shop Cannabis";
|
|
244
|
+
let pageDescription = `Browse our selection at ${location?.name}`;
|
|
245
|
+
|
|
246
|
+
if (product) {
|
|
247
|
+
pageTitle = `${product.name} | ${location?.name}`;
|
|
248
|
+
pageDescription = `${product.description?.substring(0, 155)}...`;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
return {
|
|
252
|
+
title: pageTitle,
|
|
253
|
+
description: pageDescription,
|
|
254
|
+
ogImage: location?.images?.logo,
|
|
255
|
+
canonical: `${location?.links?.storeFrontRoot}${page}`,
|
|
256
|
+
structuredData: {
|
|
257
|
+
"@context": "https://schema.org",
|
|
258
|
+
"@type": "WebPage",
|
|
259
|
+
name: pageTitle,
|
|
260
|
+
description: pageDescription,
|
|
261
|
+
},
|
|
262
|
+
customMeta: [
|
|
263
|
+
{
|
|
264
|
+
name: "robots",
|
|
265
|
+
content: "index, follow",
|
|
266
|
+
},
|
|
267
|
+
],
|
|
268
|
+
};
|
|
269
|
+
};
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Register in Module Registry
|
|
273
|
+
|
|
274
|
+
Add the function to your theme's `index.tsx`:
|
|
275
|
+
|
|
276
|
+
```typescript
|
|
277
|
+
import { RemoteModuleRegistry } from "@dutchiesdk/ecommerce-extensions-sdk";
|
|
278
|
+
import { getStoreFrontMetaFields } from "./get-meta-fields";
|
|
279
|
+
|
|
280
|
+
export default {
|
|
281
|
+
StoreFrontHeader: createLazyRemoteBoundaryComponent(() => import("./header")),
|
|
282
|
+
StoreFrontFooter: createLazyRemoteBoundaryComponent(() => import("./footer")),
|
|
283
|
+
getStoreFrontMetaFields, // Register the function
|
|
284
|
+
} satisfies RemoteModuleRegistry;
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
You may also register components for only specific menu contexts:
|
|
288
|
+
|
|
289
|
+
```typescript
|
|
290
|
+
import { RemoteModuleRegistry } from "@dutchiesdk/ecommerce-extensions-sdk";
|
|
291
|
+
|
|
292
|
+
export default {
|
|
293
|
+
StoreFrontHeader: {
|
|
294
|
+
// use one component for storefront and a different one for kiosk
|
|
295
|
+
'store-front': createLazyRemoteBoundaryComponent(() => import("./store-header")),
|
|
296
|
+
kiosk: createLazyRemoteBoundaryComponent(() => import("./kiosk-header")),
|
|
297
|
+
},
|
|
298
|
+
StoreFrontFooter: {
|
|
299
|
+
// only override storefront but not kiosk, kiosk will have default dutchie footer
|
|
300
|
+
'store-front': createLazyRemoteBoundaryComponent(() => import("./footer")),
|
|
301
|
+
},
|
|
302
|
+
} satisfies RemoteModuleRegistry;
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
### Available Data
|
|
306
|
+
|
|
307
|
+
The function receives the full `CommerceComponentsDataInterface`:
|
|
308
|
+
|
|
309
|
+
```typescript
|
|
310
|
+
{
|
|
311
|
+
menuContext: 'store-front' | 'kiosk',
|
|
312
|
+
location?: Dispensary,
|
|
313
|
+
user?: User,
|
|
314
|
+
cart?: Cart,
|
|
315
|
+
dataLoaders: {
|
|
316
|
+
product: () => Promise<Product | null>,
|
|
317
|
+
products: () => Promise<Product[]>,
|
|
318
|
+
categories: () => Promise<Category[]>,
|
|
319
|
+
// ... other loaders
|
|
320
|
+
},
|
|
321
|
+
actions: {
|
|
322
|
+
// Navigation and cart actions
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
### Example Use Cases
|
|
328
|
+
|
|
329
|
+
**Product Pages:**
|
|
330
|
+
|
|
331
|
+
```typescript
|
|
332
|
+
const product = await dataLoaders.product();
|
|
333
|
+
if (product) {
|
|
334
|
+
return {
|
|
335
|
+
title: `${product.name} - ${location?.name}`,
|
|
336
|
+
description: product.description,
|
|
337
|
+
ogImage: product.images?.[0]?.url,
|
|
338
|
+
structuredData: {
|
|
339
|
+
"@context": "https://schema.org",
|
|
340
|
+
"@type": "Product",
|
|
341
|
+
name: product.name,
|
|
342
|
+
description: product.description,
|
|
343
|
+
offers: {
|
|
344
|
+
"@type": "Offer",
|
|
345
|
+
price: product.variants?.[0]?.priceRec,
|
|
346
|
+
priceCurrency: "USD",
|
|
347
|
+
},
|
|
348
|
+
},
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
**Category Pages:**
|
|
354
|
+
|
|
355
|
+
```typescript
|
|
356
|
+
const categories = await dataLoaders.categories();
|
|
357
|
+
const pathname = window.location.pathname;
|
|
358
|
+
const categorySlug = pathname.split("/").pop();
|
|
359
|
+
const category = categories.find((c) => c.slug === categorySlug);
|
|
360
|
+
|
|
361
|
+
if (category) {
|
|
362
|
+
return {
|
|
363
|
+
title: `${category.name} | ${location?.name}`,
|
|
364
|
+
description: `Shop ${category.name} products at ${location?.name}`,
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
**Home Page:**
|
|
370
|
+
|
|
371
|
+
```typescript
|
|
372
|
+
if (pathname === "/" || pathname === "") {
|
|
373
|
+
return {
|
|
374
|
+
title: `${location?.name} - Cannabis Dispensary`,
|
|
375
|
+
description: `Shop cannabis products online at ${location?.name}`,
|
|
376
|
+
structuredData: {
|
|
377
|
+
"@context": "https://schema.org",
|
|
378
|
+
"@type": "Organization",
|
|
379
|
+
name: location?.name,
|
|
380
|
+
url: location?.links?.storeFrontRoot,
|
|
381
|
+
logo: location?.images?.logo,
|
|
382
|
+
},
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
### Notes
|
|
388
|
+
|
|
389
|
+
- The function is called on every page navigation
|
|
390
|
+
- Async operations (like `dataLoaders.product()`) are supported
|
|
391
|
+
- Return values are rendered into `<head>` tags automatically
|
|
392
|
+
- The title tag will update dynamically as meta fields load
|
|
393
|
+
- All fields are optional - return only what's needed for each page
|
|
394
|
+
|
|
395
|
+
### Migration Strategy
|
|
396
|
+
|
|
397
|
+
If you have an existing theme using the `StoreFrontMeta` component:
|
|
398
|
+
|
|
399
|
+
1. **Implement the function**: Add `getStoreFrontMetaFields` to your theme's module registry
|
|
400
|
+
2. **Test both approaches**: Keep your existing `StoreFrontMeta` component during the transition
|
|
401
|
+
3. **Feature flag controls behavior**: Dutchie's feature flag determines which implementation is used
|
|
402
|
+
4. **Future-proof**: Once the rollout completes, only the function approach will be supported
|
|
403
|
+
|
|
194
404
|
## Best Practices
|
|
195
405
|
|
|
196
406
|
### Data Loading
|
|
@@ -218,11 +428,7 @@ Any uncaught errors will be caught by a Dutchie error boundary, and the fallback
|
|
|
218
428
|
Leverage the provided types for better development experience:
|
|
219
429
|
|
|
220
430
|
```tsx
|
|
221
|
-
import {
|
|
222
|
-
Product,
|
|
223
|
-
Category,
|
|
224
|
-
useDataBridge,
|
|
225
|
-
} from "@dutchie/ecommerce-extensions-sdk";
|
|
431
|
+
import { Product, Category, useDataBridge } from "@dutchie/ecommerce-extensions-sdk";
|
|
226
432
|
|
|
227
433
|
interface ProductFilterProps {
|
|
228
434
|
products: Product[];
|
|
@@ -230,11 +436,7 @@ interface ProductFilterProps {
|
|
|
230
436
|
onFilterChange: (categoryId: string) => void;
|
|
231
437
|
}
|
|
232
438
|
|
|
233
|
-
const ProductFilter: React.FC<ProductFilterProps> = ({
|
|
234
|
-
products,
|
|
235
|
-
categories,
|
|
236
|
-
onFilterChange,
|
|
237
|
-
}) => {
|
|
439
|
+
const ProductFilter: React.FC<ProductFilterProps> = ({ products, categories, onFilterChange }) => {
|
|
238
440
|
// Implementation
|
|
239
441
|
};
|
|
240
442
|
```
|
|
@@ -312,3 +514,11 @@ For technical support and questions about the Dutchie Ecommerce Extensions SDK:
|
|
|
312
514
|
- 📧 Contact your Dutchie agency partner representative
|
|
313
515
|
- 📚 Refer to the Dutchie Pro platform documentation
|
|
314
516
|
- 🐛 Report issues through the official Dutchie support channels
|
|
517
|
+
|
|
518
|
+
## Updates
|
|
519
|
+
|
|
520
|
+
Stay up to date with this SDK by checking here for changes, and updating to the latest version with:
|
|
521
|
+
|
|
522
|
+
```bash
|
|
523
|
+
npm install @dutchiesdk/ecommerce-extensions-sdk@latest
|
|
524
|
+
```
|
|
@@ -30,7 +30,7 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
30
30
|
useDataBridge: ()=>useDataBridge
|
|
31
31
|
});
|
|
32
32
|
const external_react_namespaceObject = require("react");
|
|
33
|
-
const DataBridgeVersion = '0.
|
|
33
|
+
const DataBridgeVersion = '0.18.0';
|
|
34
34
|
const DataBridgeContext = (0, external_react_namespaceObject.createContext)(void 0);
|
|
35
35
|
const useDataBridge = ()=>{
|
|
36
36
|
const context = (0, external_react_namespaceObject.useContext)(DataBridgeContext);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createContext, useContext, useEffect, useState } from "react";
|
|
2
|
-
const DataBridgeVersion = '0.
|
|
2
|
+
const DataBridgeVersion = '0.18.0';
|
|
3
3
|
const DataBridgeContext = createContext(void 0);
|
|
4
4
|
const useDataBridge = ()=>{
|
|
5
5
|
const context = useContext(DataBridgeContext);
|
|
@@ -1,21 +1,71 @@
|
|
|
1
1
|
import type React from 'react';
|
|
2
|
+
import type { MenuContext } from './data';
|
|
2
3
|
import type { Events } from './events';
|
|
4
|
+
import type { CommerceComponentsDataInterface } from './interface';
|
|
3
5
|
export type RemoteBoundaryComponent<P = {}> = React.FC<P> & {
|
|
4
6
|
DataBridgeVersion: string;
|
|
5
7
|
};
|
|
8
|
+
export type MenuSpecificRemoteComponent = {
|
|
9
|
+
[key in MenuContext]?: RemoteBoundaryComponent;
|
|
10
|
+
};
|
|
11
|
+
export type ModuleRegistryEntry = MenuSpecificRemoteComponent | RemoteBoundaryComponent;
|
|
6
12
|
export type RoutablePageRegistryEntry = {
|
|
7
13
|
component: RemoteBoundaryComponent;
|
|
8
14
|
path: string;
|
|
9
15
|
};
|
|
16
|
+
/**
|
|
17
|
+
* Meta fields for page metadata (SEO, social sharing, etc.)
|
|
18
|
+
*/
|
|
19
|
+
export type MetaFields = {
|
|
20
|
+
/** Page title (rendered in <title> tag) */
|
|
21
|
+
title?: string;
|
|
22
|
+
/** Page description (rendered in <meta name="description"> tag) */
|
|
23
|
+
description?: string;
|
|
24
|
+
/** Open Graph image URL */
|
|
25
|
+
ogImage?: string;
|
|
26
|
+
/** Canonical URL */
|
|
27
|
+
canonical?: string;
|
|
28
|
+
/** JSON-LD structured data for rich snippets */
|
|
29
|
+
structuredData?: Record<string, any>;
|
|
30
|
+
/** Additional custom meta tags */
|
|
31
|
+
customMeta?: Array<{
|
|
32
|
+
name?: string;
|
|
33
|
+
property?: string;
|
|
34
|
+
content: string;
|
|
35
|
+
}>;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Function that returns meta fields for the current page.
|
|
39
|
+
* Receives the data bridge context as a parameter, allowing access to
|
|
40
|
+
* data loaders, cart, user, location, and actions.
|
|
41
|
+
*
|
|
42
|
+
* @param data - The commerce components data interface with loaders and state
|
|
43
|
+
* @returns Meta fields for the current page (title, description, OG tags, etc.)
|
|
44
|
+
*/
|
|
45
|
+
export type StoreFrontMetaFieldsFunction = (data: CommerceComponentsDataInterface) => MetaFields | Promise<MetaFields>;
|
|
10
46
|
export type RemoteModuleRegistry = {
|
|
11
47
|
RouteablePages?: RoutablePageRegistryEntry[];
|
|
12
|
-
StoreFrontHeader?:
|
|
48
|
+
StoreFrontHeader?: ModuleRegistryEntry;
|
|
49
|
+
StoreFrontNavigation?: ModuleRegistryEntry;
|
|
50
|
+
StoreFrontFooter?: ModuleRegistryEntry;
|
|
51
|
+
StoreFrontCarouselInterstitials?: ModuleRegistryEntry[];
|
|
52
|
+
StoreFrontHero?: ModuleRegistryEntry;
|
|
53
|
+
ProductDetailsPrimary?: ModuleRegistryEntry;
|
|
54
|
+
/**
|
|
55
|
+
* Function that provides meta fields for the current page.
|
|
56
|
+
* Replaces the StoreFrontMeta component approach.
|
|
57
|
+
*
|
|
58
|
+
* Called by the host app with the full data bridge context:
|
|
59
|
+
* `const metaFields = registry.getStoreFrontMetaFields?.(dataBridgeData)`
|
|
60
|
+
*/
|
|
61
|
+
getStoreFrontMetaFields?: StoreFrontMetaFieldsFunction;
|
|
62
|
+
events?: Events;
|
|
63
|
+
/**
|
|
64
|
+
* @deprecated Use getStoreFrontMetaFields instead
|
|
65
|
+
*/
|
|
13
66
|
StoreFrontMeta?: RemoteBoundaryComponent;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
StoreFrontHero?: RemoteBoundaryComponent;
|
|
67
|
+
/**
|
|
68
|
+
* @deprecated Use getStoreFrontMetaFields instead
|
|
69
|
+
*/
|
|
18
70
|
ProductDetailsMeta?: RemoteBoundaryComponent;
|
|
19
|
-
ProductDetailsPrimary?: RemoteBoundaryComponent;
|
|
20
|
-
events?: Events;
|
|
21
71
|
};
|
|
@@ -1,21 +1,71 @@
|
|
|
1
1
|
import type React from 'react';
|
|
2
|
+
import type { MenuContext } from './data';
|
|
2
3
|
import type { Events } from './events';
|
|
4
|
+
import type { CommerceComponentsDataInterface } from './interface';
|
|
3
5
|
export type RemoteBoundaryComponent<P = {}> = React.FC<P> & {
|
|
4
6
|
DataBridgeVersion: string;
|
|
5
7
|
};
|
|
8
|
+
export type MenuSpecificRemoteComponent = {
|
|
9
|
+
[key in MenuContext]?: RemoteBoundaryComponent;
|
|
10
|
+
};
|
|
11
|
+
export type ModuleRegistryEntry = MenuSpecificRemoteComponent | RemoteBoundaryComponent;
|
|
6
12
|
export type RoutablePageRegistryEntry = {
|
|
7
13
|
component: RemoteBoundaryComponent;
|
|
8
14
|
path: string;
|
|
9
15
|
};
|
|
16
|
+
/**
|
|
17
|
+
* Meta fields for page metadata (SEO, social sharing, etc.)
|
|
18
|
+
*/
|
|
19
|
+
export type MetaFields = {
|
|
20
|
+
/** Page title (rendered in <title> tag) */
|
|
21
|
+
title?: string;
|
|
22
|
+
/** Page description (rendered in <meta name="description"> tag) */
|
|
23
|
+
description?: string;
|
|
24
|
+
/** Open Graph image URL */
|
|
25
|
+
ogImage?: string;
|
|
26
|
+
/** Canonical URL */
|
|
27
|
+
canonical?: string;
|
|
28
|
+
/** JSON-LD structured data for rich snippets */
|
|
29
|
+
structuredData?: Record<string, any>;
|
|
30
|
+
/** Additional custom meta tags */
|
|
31
|
+
customMeta?: Array<{
|
|
32
|
+
name?: string;
|
|
33
|
+
property?: string;
|
|
34
|
+
content: string;
|
|
35
|
+
}>;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Function that returns meta fields for the current page.
|
|
39
|
+
* Receives the data bridge context as a parameter, allowing access to
|
|
40
|
+
* data loaders, cart, user, location, and actions.
|
|
41
|
+
*
|
|
42
|
+
* @param data - The commerce components data interface with loaders and state
|
|
43
|
+
* @returns Meta fields for the current page (title, description, OG tags, etc.)
|
|
44
|
+
*/
|
|
45
|
+
export type StoreFrontMetaFieldsFunction = (data: CommerceComponentsDataInterface) => MetaFields | Promise<MetaFields>;
|
|
10
46
|
export type RemoteModuleRegistry = {
|
|
11
47
|
RouteablePages?: RoutablePageRegistryEntry[];
|
|
12
|
-
StoreFrontHeader?:
|
|
48
|
+
StoreFrontHeader?: ModuleRegistryEntry;
|
|
49
|
+
StoreFrontNavigation?: ModuleRegistryEntry;
|
|
50
|
+
StoreFrontFooter?: ModuleRegistryEntry;
|
|
51
|
+
StoreFrontCarouselInterstitials?: ModuleRegistryEntry[];
|
|
52
|
+
StoreFrontHero?: ModuleRegistryEntry;
|
|
53
|
+
ProductDetailsPrimary?: ModuleRegistryEntry;
|
|
54
|
+
/**
|
|
55
|
+
* Function that provides meta fields for the current page.
|
|
56
|
+
* Replaces the StoreFrontMeta component approach.
|
|
57
|
+
*
|
|
58
|
+
* Called by the host app with the full data bridge context:
|
|
59
|
+
* `const metaFields = registry.getStoreFrontMetaFields?.(dataBridgeData)`
|
|
60
|
+
*/
|
|
61
|
+
getStoreFrontMetaFields?: StoreFrontMetaFieldsFunction;
|
|
62
|
+
events?: Events;
|
|
63
|
+
/**
|
|
64
|
+
* @deprecated Use getStoreFrontMetaFields instead
|
|
65
|
+
*/
|
|
13
66
|
StoreFrontMeta?: RemoteBoundaryComponent;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
StoreFrontHero?: RemoteBoundaryComponent;
|
|
67
|
+
/**
|
|
68
|
+
* @deprecated Use getStoreFrontMetaFields instead
|
|
69
|
+
*/
|
|
18
70
|
ProductDetailsMeta?: RemoteBoundaryComponent;
|
|
19
|
-
ProductDetailsPrimary?: RemoteBoundaryComponent;
|
|
20
|
-
events?: Events;
|
|
21
71
|
};
|