@coveo/shopify 1.2.2-pre.e593f8f8f7 → 1.3.0-pre.49914cd105

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
@@ -6,7 +6,7 @@ It includes functions to fetch app proxy configurations and build a commerce eng
6
6
 
7
7
  ## Benefits
8
8
 
9
- Using the `@coveo/shopify` package ensures that the commerce engine will emit events using the same `clientId` both inside and outside Shopify Web Pixels. This provides consistent tracking and analytics across the entire Shopify ecosystem.
9
+ Using the `@coveo/shopify` package ensures that the commerce engine will emit events using the same `clientId` both inside and outside Shopify Web Pixels. This provides consistent tracking and analytics across the entire Shopify ecosystem. When initializing the commerce engine, a custom event is emitted using the `coveo_shopify_config` key. This event enables Shopify Web Pixels to access the app proxy configuration, ensuring consistent tracking and personalization across storefronts and pixels.
10
10
 
11
11
  ## Installation
12
12
 
@@ -41,7 +41,7 @@ A promise that resolves to an object containing:
41
41
  #### Example
42
42
 
43
43
  ```typescript
44
- import {fetchAppProxyConfig} from '@coveo/shopify/headless';
44
+ import {fetchAppProxyConfig} from '@coveo/shopify/headless/commerce';
45
45
 
46
46
  const config = await fetchAppProxyConfig({
47
47
  marketId: 'market_123432',
@@ -67,7 +67,7 @@ A configured commerce engine instance.
67
67
 
68
68
  ```typescript
69
69
  <script type="module">
70
- import {buildShopifyCommerceEngine, fetchAppProxyConfig} from 'https://static.cloud.coveo.com/shopify/v1/headless.esm.js';
70
+ import {buildShopifyCommerceEngine, fetchAppProxyConfig} from 'https://static.cloud.coveo.com/shopify/v1/headless/commerce.esm.js';
71
71
 
72
72
  const config = await fetchAppProxyConfig({marketId: 'market_123432'});
73
73
  const engine = buildShopifyCommerceEngine({
@@ -102,25 +102,31 @@ console.log(engine);
102
102
  </script>
103
103
  ```
104
104
 
105
- ### `getShopifyCookie`
105
+ ### `getClientId`
106
106
 
107
- Retrieves the value of a specified Shopify cookie by its name.
107
+ Generates a unique client identifier for the Shopify store, based on the value of the Shopify `_shopify_y` cookie. This ensures consistent identification of users across storefronts and Shopify Web Pixels.
108
108
 
109
- #### Returns
109
+ #### Parameters
110
110
 
111
- The value of the specified cookie, or `null` if the cookie is not found.
111
+ - `shopifyCookie` (required): The value of the Shopify `_shopify_y` cookie.
112
112
 
113
- #### Notes
113
+ #### Returns
114
114
 
115
- This function is intended for use in **browser environments only**, as it relies on the `document.cookie` API. Attempting to use this function in non-browser environments will result in an error or undefined behavior.
115
+ A version 5 UUID string uniquely representing the client.
116
116
 
117
117
  #### Example
118
118
 
119
119
  ```typescript
120
- import {getShopifyCookie} from '@coveo/shopify';
120
+ import {getClientId, getShopifyCookie} from '@coveo/shopify/utilities';
121
121
 
122
122
  const shopifyCookie = getShopifyCookie();
123
- console.log(shopifyCookie);
123
+ const clientId = getClientId(shopifyCookie!);
124
+ console.log(clientId);
124
125
  ```
125
126
 
127
+ **Key constants:**
128
+
129
+ - `SHOPIFY_COOKIE_KEY`: The name of the Shopify cookie used for client identification (`_shopify_y`).
130
+ - `COVEO_SHOPIFY_CONFIG_KEY`: The key for the custom event and cookie used to share app proxy configuration (`coveo_shopify_config`).
131
+
126
132
  ---
@@ -0,0 +1,9 @@
1
+ export declare const SHOPIFY_COOKIE_KEY = "_shopify_y";
2
+ /**
3
+ * The key used for storing and emitting the app proxy configuration.
4
+ *
5
+ * This constant serves two purposes:
6
+ * - It is the name of the custom event emitted to pass app proxy configuration to the web pixel.
7
+ * - It is also the name of the cookie where the app proxy configuration information is stored.
8
+ */
9
+ export declare const COVEO_SHOPIFY_CONFIG_KEY = "coveo_shopify_config";
@@ -0,0 +1,9 @@
1
+ export const SHOPIFY_COOKIE_KEY = '_shopify_y';
2
+ /**
3
+ * The key used for storing and emitting the app proxy configuration.
4
+ *
5
+ * This constant serves two purposes:
6
+ * - It is the name of the custom event emitted to pass app proxy configuration to the web pixel.
7
+ * - It is also the name of the cookie where the app proxy configuration information is stored.
8
+ */
9
+ export const COVEO_SHOPIFY_CONFIG_KEY = 'coveo_shopify_config';
@@ -1,32 +1,24 @@
1
1
  import { CommerceEngineOptions } from '@coveo/headless/commerce';
2
- import { CustomEnvironment } from '@coveo/relay';
2
+ import { ShopifyCustomEnvironment } from '../types';
3
+ export { SHOPIFY_COOKIE_KEY, COVEO_SHOPIFY_CONFIG_KEY } from '../constants';
3
4
  export * from '@coveo/headless/commerce';
4
- export * from './utilities';
5
- export declare const SHOPIFY_COOKIE_KEY = "_shopify_y";
6
- export interface AppProxyOptions {
7
- appProxyUrl?: string;
8
- marketId: string;
9
- }
10
- export interface AppProxyResponse {
11
- accessToken: string;
12
- organizationId: string;
13
- environment: CommerceEngineOptions['configuration']['environment'];
14
- trackingId: string;
15
- }
5
+ export * from '../utilities';
6
+ export type { AppProxyConfig, AppProxyResponse, ShopifyCustomEnvironment, } from '../types';
16
7
  /**
17
- * Fetches configuration from the app proxy.
8
+ * Options for building a Shopify commerce engine.
9
+ *
10
+ * @typedef BuildShopifyCommerceEngineOptions
11
+ * @property {CommerceEngineOptions} commerceEngineOptions - The core options for configuring the commerce engine.
12
+ * @property {ShopifyCustomEnvironment} [environment] - Optional browser environment; if not provided, a default one is created. Mainly useful when not running in a browser environment.
13
+ * @property {string} [shopifyCookie] - Optional value of the "_shopify_y" cookie. If not provided, it will attempt to retrieve it from the browser's cookies.
18
14
  *
19
- * Performs an HTTP GET request to retrieve the app proxy configuration using the provided marketId.
20
- * The fetched response is parsed as JSON and returned.
15
+ * @remarks
16
+ * The `generateUUID` and `storage` properties are omitted from the custom environment for Shopify
17
+ * to ensure that client IDs are generated consistently across web pixels and storefronts. This is
18
+ * critical for maintaining a unified tracking and personalization experience.
21
19
  *
22
- * @param appProxyUrl - The URL template for the app proxy endpoint. Defaults to '/apps/coveo'.
23
- * @param marketId - The unique market identifier used as a query parameter.
24
- * @returns A promise that resolves to an object containing the access token, organization ID,
25
- * environment, and tracking ID.
26
20
  */
27
- export declare function fetchAppProxyConfig({ appProxyUrl, marketId, }: AppProxyOptions): Promise<AppProxyResponse>;
28
- type ShopifyCustomEnvironment = Omit<CustomEnvironment, 'storage' | 'generateUUID'>;
29
- interface BuildShopifyCommerceEngineOptions {
21
+ export interface BuildShopifyCommerceEngineOptions {
30
22
  commerceEngineOptions: CommerceEngineOptions;
31
23
  shopifyCookie?: string;
32
24
  environment?: ShopifyCustomEnvironment;
@@ -37,6 +29,7 @@ interface BuildShopifyCommerceEngineOptions {
37
29
  * This function initializes a commerce engine instance specific to a Shopify store by:
38
30
  * - Creating or using an existing browser environment.
39
31
  * - Retrieving the "_shopify_y" cookie to confirm it is running in a Shopify context.
32
+ * - Emitting a custom event with the app proxy response to enable tracking and analytics with shopify webpixels.
40
33
  * - Storing a client identifier derived from the shop and cookie value in the browser environment's storage.
41
34
  * - Building and returning the commerce engine with the provided options.
42
35
  *
@@ -52,14 +45,3 @@ interface BuildShopifyCommerceEngineOptions {
52
45
  * @throws Error if the required "_shopify_y" cookie is not found, ensuring the code runs within a Shopify store.
53
46
  */
54
47
  export declare function buildShopifyCommerceEngine({ commerceEngineOptions, shopifyCookie, environment, }: BuildShopifyCommerceEngineOptions): import("@coveo/headless/commerce").CommerceEngine<{}>;
55
- /**
56
- * Retrieves the value of a specified Shopify cookie by its name.
57
- *
58
- * @remarks
59
- * This function is intended for use in browser environments only, as it relies on the `document.cookie` API.
60
- * Attempting to use this function in non-browser environments will result in an error or undefined behavior.
61
- *
62
- * @param name - The name of the Shopify cookie to retrieve. Defaults to `'_shopify_y'`.
63
- * @returns The value of the specified cookie, or `null` if the cookie is not found.
64
- */
65
- export declare function getShopifyCookie(name?: string): string | null;
@@ -0,0 +1,112 @@
1
+ /**
2
+ * @license
3
+ *
4
+ * Copyright 2025 Coveo Solutions Inc.
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+
19
+ // src/headless/commerce.ts
20
+ import {
21
+ buildCommerceEngine
22
+ } from "@coveo/headless/commerce";
23
+ import { buildBrowserEnvironment } from "@coveo/relay";
24
+
25
+ // src/constants.ts
26
+ var SHOPIFY_COOKIE_KEY = "_shopify_y";
27
+ var COVEO_SHOPIFY_CONFIG_KEY = "coveo_shopify_config";
28
+
29
+ // src/types.ts
30
+ function getShopifyCustomEnvironment(environment) {
31
+ const { storage, generateUUID, ...rest } = environment;
32
+ return rest;
33
+ }
34
+
35
+ // src/utilities/clientid.ts
36
+ import { v5 } from "uuid";
37
+ var UUID_NAMESPACE = "c2db3701-991e-424d-b117-03e30d43b651";
38
+ function getClientId(shopifyCookie) {
39
+ return v5(shopifyCookie, UUID_NAMESPACE);
40
+ }
41
+
42
+ // src/utilities/shopify.ts
43
+ function getShopifyCookie(name = SHOPIFY_COOKIE_KEY) {
44
+ const match = document.cookie.match(
45
+ new RegExp("(?:^|;\\s*)" + name + "=([^;]*)")
46
+ );
47
+ return match ? decodeURIComponent(match[1]) : null;
48
+ }
49
+ function publishCustomShopifyEvent(key, customData) {
50
+ if (typeof window.Shopify?.analytics?.publish === "function") {
51
+ window.Shopify.analytics.publish(key, customData);
52
+ }
53
+ }
54
+
55
+ // src/headless/commerce.ts
56
+ export * from "@coveo/headless/commerce";
57
+
58
+ // src/utilities/app-proxy.ts
59
+ async function fetchAppProxyConfig({
60
+ appProxyUrl = "/apps/coveo",
61
+ marketId
62
+ }) {
63
+ const response = await fetch(`${appProxyUrl}?marketId=${marketId}]`);
64
+ return response.json();
65
+ }
66
+
67
+ // src/headless/commerce.ts
68
+ function buildShopifyCommerceEngine({
69
+ commerceEngineOptions,
70
+ shopifyCookie,
71
+ environment
72
+ }) {
73
+ const customEnvironment = environment ?? getShopifyCustomEnvironment(buildBrowserEnvironment());
74
+ const cookie = shopifyCookie || getShopifyCookie();
75
+ if (!commerceEngineOptions.configuration.analytics.trackingId) {
76
+ throw new Error(
77
+ "The configuration for the commerce engine must include an analytics tracking ID."
78
+ );
79
+ }
80
+ if (!cookie) {
81
+ throw new Error(
82
+ "Unable to find the _shopify_y cookie. Please ensure you are running this code in a Shopify store."
83
+ );
84
+ }
85
+ const appProxyResponse = {
86
+ accessToken: commerceEngineOptions.configuration.accessToken,
87
+ organizationId: commerceEngineOptions.configuration.organizationId,
88
+ environment: commerceEngineOptions.configuration.environment,
89
+ trackingId: commerceEngineOptions.configuration.analytics.trackingId
90
+ };
91
+ publishCustomShopifyEvent(
92
+ COVEO_SHOPIFY_CONFIG_KEY,
93
+ appProxyResponse
94
+ );
95
+ const clientId = getClientId(cookie);
96
+ const engine = buildCommerceEngine(commerceEngineOptions);
97
+ engine.relay.updateConfig({
98
+ environment: {
99
+ ...customEnvironment,
100
+ generateUUID: () => clientId
101
+ }
102
+ });
103
+ return engine;
104
+ }
105
+ export {
106
+ COVEO_SHOPIFY_CONFIG_KEY,
107
+ SHOPIFY_COOKIE_KEY,
108
+ buildShopifyCommerceEngine,
109
+ fetchAppProxyConfig,
110
+ getClientId,
111
+ getShopifyCookie
112
+ };
@@ -1,30 +1,20 @@
1
1
  import { buildCommerceEngine, } from '@coveo/headless/commerce';
2
2
  import { buildBrowserEnvironment } from '@coveo/relay';
3
- import { getClientId } from './utilities';
3
+ import { COVEO_SHOPIFY_CONFIG_KEY } from '../constants';
4
+ import { getShopifyCustomEnvironment, } from '../types';
5
+ import { getClientId } from '../utilities/clientid';
6
+ import { publishCustomShopifyEvent } from '../utilities/shopify';
7
+ import { getShopifyCookie } from '../utilities/shopify';
8
+ export { SHOPIFY_COOKIE_KEY, COVEO_SHOPIFY_CONFIG_KEY } from '../constants';
4
9
  export * from '@coveo/headless/commerce';
5
- export * from './utilities';
6
- export const SHOPIFY_COOKIE_KEY = '_shopify_y';
7
- /**
8
- * Fetches configuration from the app proxy.
9
- *
10
- * Performs an HTTP GET request to retrieve the app proxy configuration using the provided marketId.
11
- * The fetched response is parsed as JSON and returned.
12
- *
13
- * @param appProxyUrl - The URL template for the app proxy endpoint. Defaults to '/apps/coveo'.
14
- * @param marketId - The unique market identifier used as a query parameter.
15
- * @returns A promise that resolves to an object containing the access token, organization ID,
16
- * environment, and tracking ID.
17
- */
18
- export async function fetchAppProxyConfig({ appProxyUrl = '/apps/coveo', marketId, }) {
19
- const response = await fetch(`${appProxyUrl}?marketId=${marketId}]`);
20
- return response.json();
21
- }
10
+ export * from '../utilities';
22
11
  /**
23
12
  * Builds the commerce engine for a Shopify store.
24
13
  *
25
14
  * This function initializes a commerce engine instance specific to a Shopify store by:
26
15
  * - Creating or using an existing browser environment.
27
16
  * - Retrieving the "_shopify_y" cookie to confirm it is running in a Shopify context.
17
+ * - Emitting a custom event with the app proxy response to enable tracking and analytics with shopify webpixels.
28
18
  * - Storing a client identifier derived from the shop and cookie value in the browser environment's storage.
29
19
  * - Building and returning the commerce engine with the provided options.
30
20
  *
@@ -42,9 +32,19 @@ export async function fetchAppProxyConfig({ appProxyUrl = '/apps/coveo', marketI
42
32
  export function buildShopifyCommerceEngine({ commerceEngineOptions, shopifyCookie, environment, }) {
43
33
  const customEnvironment = environment ?? getShopifyCustomEnvironment(buildBrowserEnvironment());
44
34
  const cookie = shopifyCookie || getShopifyCookie();
35
+ if (!commerceEngineOptions.configuration.analytics.trackingId) {
36
+ throw new Error('The configuration for the commerce engine must include an analytics tracking ID.');
37
+ }
45
38
  if (!cookie) {
46
39
  throw new Error('Unable to find the _shopify_y cookie. Please ensure you are running this code in a Shopify store.');
47
40
  }
41
+ const appProxyResponse = {
42
+ accessToken: commerceEngineOptions.configuration.accessToken,
43
+ organizationId: commerceEngineOptions.configuration.organizationId,
44
+ environment: commerceEngineOptions.configuration.environment,
45
+ trackingId: commerceEngineOptions.configuration.analytics.trackingId,
46
+ };
47
+ publishCustomShopifyEvent(COVEO_SHOPIFY_CONFIG_KEY, appProxyResponse);
48
48
  const clientId = getClientId(cookie);
49
49
  const engine = buildCommerceEngine(commerceEngineOptions);
50
50
  engine.relay.updateConfig({
@@ -55,21 +55,3 @@ export function buildShopifyCommerceEngine({ commerceEngineOptions, shopifyCooki
55
55
  });
56
56
  return engine;
57
57
  }
58
- function getShopifyCustomEnvironment(environment) {
59
- const { storage, generateUUID, ...rest } = environment;
60
- return rest;
61
- }
62
- /**
63
- * Retrieves the value of a specified Shopify cookie by its name.
64
- *
65
- * @remarks
66
- * This function is intended for use in browser environments only, as it relies on the `document.cookie` API.
67
- * Attempting to use this function in non-browser environments will result in an error or undefined behavior.
68
- *
69
- * @param name - The name of the Shopify cookie to retrieve. Defaults to `'_shopify_y'`.
70
- * @returns The value of the specified cookie, or `null` if the cookie is not found.
71
- */
72
- export function getShopifyCookie(name = SHOPIFY_COOKIE_KEY) {
73
- const match = document.cookie.match(new RegExp('(?:^|;\\s*)' + name + '=([^;]*)'));
74
- return match ? decodeURIComponent(match[1]) : null;
75
- }
@@ -0,0 +1 @@
1
+ export * from './commerce';
@@ -0,0 +1 @@
1
+ export * from './commerce';
@@ -0,0 +1,47 @@
1
+ import { SearchEngineOptions } from '@coveo/headless';
2
+ import { ShopifyCustomEnvironment } from '../types';
3
+ export { SHOPIFY_COOKIE_KEY, COVEO_SHOPIFY_CONFIG_KEY } from '../constants';
4
+ export type { AppProxyConfig, AppProxyResponse, ShopifyCustomEnvironment, } from '../types';
5
+ export * from '@coveo/headless';
6
+ export * from '../utilities';
7
+ /**
8
+ * Options for building a Shopify search engine instance.
9
+ *
10
+ * @typedef BuildShopifySearchEngineOptions
11
+ * @property {SearchEngineOptions} searchEngineOptions - The core options for configuring the search engine.
12
+ * @property {ShopifyCustomEnvironment} [environment] - Optional browser environment; if not provided, a default one is created. Mainly useful when not running in a browser environment.
13
+ * @property {string} [shopifyCookie] - Optional value of the "_shopify_y" cookie. If not provided, it will attempt to retrieve it from the browser's cookies.
14
+ *
15
+ * @remarks
16
+ * The `generateUUID` and `storage` properties are omitted from the custom environment for Shopify
17
+ * to ensure that client IDs are generated consistently across web pixels and storefronts. This is
18
+ * critical for maintaining a unified tracking and personalization experience.
19
+ *
20
+ */
21
+ export interface BuildShopifySearchEngineOptions {
22
+ searchEngineOptions: SearchEngineOptions;
23
+ environment?: ShopifyCustomEnvironment;
24
+ shopifyCookie?: string;
25
+ }
26
+ /**
27
+ * Builds the search engine for a Shopify store.
28
+ *
29
+ * This function initializes a search engine instance specific to a Shopify store by:
30
+ * - Creating or using an existing browser environment.
31
+ * - Retrieving the "_shopify_y" cookie to confirm it is running in a Shopify context.
32
+ * - Emitting a custom event with the app proxy response to enable tracking and analytics with shopify webpixels.
33
+ * - Storing a client identifier derived from the shop and cookie value in the browser environment's storage.
34
+ * - Building and returning the search engine with the provided options.
35
+ *
36
+ * @remarks
37
+ * The `generateUUID` and `storage` properties are omitted from the custom environment for Shopify
38
+ * to ensure that client IDs are generated consistently across web pixels and storefronts. This is
39
+ * critical for maintaining a unified tracking and personalization experience.
40
+ *
41
+ * @param searchEngineOptions - Options to configure the search engine.
42
+ * @param shopifyCookie - Optional value of the "_shopify_y" cookie. If not provided, it will attempt to retrieve it from the browser's cookies.
43
+ * @param environment - Optional browser environment; if not provided, a default one is created. Mainly useful when not running in a browser environment.
44
+ * @returns The constructed search engine instance.
45
+ * @throws Error if the required "_shopify_y" cookie is not found, ensuring the code runs within a Shopify store.
46
+ */
47
+ export declare function buildShopifySearchEngine({ searchEngineOptions, environment, shopifyCookie, }: BuildShopifySearchEngineOptions): import("@coveo/headless").SearchEngine<{}>;
@@ -0,0 +1,110 @@
1
+ /**
2
+ * @license
3
+ *
4
+ * Copyright 2025 Coveo Solutions Inc.
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+
19
+ // src/headless/search.ts
20
+ import { buildSearchEngine } from "@coveo/headless";
21
+ import { buildBrowserEnvironment } from "@coveo/relay";
22
+
23
+ // src/constants.ts
24
+ var SHOPIFY_COOKIE_KEY = "_shopify_y";
25
+ var COVEO_SHOPIFY_CONFIG_KEY = "coveo_shopify_config";
26
+
27
+ // src/types.ts
28
+ function getShopifyCustomEnvironment(environment) {
29
+ const { storage, generateUUID, ...rest } = environment;
30
+ return rest;
31
+ }
32
+
33
+ // src/utilities/clientid.ts
34
+ import { v5 } from "uuid";
35
+ var UUID_NAMESPACE = "c2db3701-991e-424d-b117-03e30d43b651";
36
+ function getClientId(shopifyCookie) {
37
+ return v5(shopifyCookie, UUID_NAMESPACE);
38
+ }
39
+
40
+ // src/utilities/shopify.ts
41
+ function getShopifyCookie(name = SHOPIFY_COOKIE_KEY) {
42
+ const match = document.cookie.match(
43
+ new RegExp("(?:^|;\\s*)" + name + "=([^;]*)")
44
+ );
45
+ return match ? decodeURIComponent(match[1]) : null;
46
+ }
47
+ function publishCustomShopifyEvent(key, customData) {
48
+ if (typeof window.Shopify?.analytics?.publish === "function") {
49
+ window.Shopify.analytics.publish(key, customData);
50
+ }
51
+ }
52
+
53
+ // src/headless/search.ts
54
+ export * from "@coveo/headless";
55
+
56
+ // src/utilities/app-proxy.ts
57
+ async function fetchAppProxyConfig({
58
+ appProxyUrl = "/apps/coveo",
59
+ marketId
60
+ }) {
61
+ const response = await fetch(`${appProxyUrl}?marketId=${marketId}]`);
62
+ return response.json();
63
+ }
64
+
65
+ // src/headless/search.ts
66
+ function buildShopifySearchEngine({
67
+ searchEngineOptions,
68
+ environment,
69
+ shopifyCookie
70
+ }) {
71
+ const customEnvironment = environment ?? getShopifyCustomEnvironment(buildBrowserEnvironment());
72
+ const cookie = shopifyCookie || getShopifyCookie();
73
+ if (!searchEngineOptions.configuration.analytics?.trackingId) {
74
+ throw new Error(
75
+ "The configuration for the search engine must include an analytics tracking ID."
76
+ );
77
+ }
78
+ if (!cookie) {
79
+ throw new Error(
80
+ "Unable to find the _shopify_y cookie. Please ensure you are running this code in a Shopify store."
81
+ );
82
+ }
83
+ const appProxyResponse = {
84
+ accessToken: searchEngineOptions.configuration.accessToken,
85
+ organizationId: searchEngineOptions.configuration.organizationId,
86
+ environment: searchEngineOptions.configuration.environment,
87
+ trackingId: searchEngineOptions.configuration.analytics.trackingId
88
+ };
89
+ publishCustomShopifyEvent(
90
+ COVEO_SHOPIFY_CONFIG_KEY,
91
+ appProxyResponse
92
+ );
93
+ const clientId = getClientId(cookie);
94
+ const engine = buildSearchEngine(searchEngineOptions);
95
+ engine.relay.updateConfig({
96
+ environment: {
97
+ ...customEnvironment,
98
+ generateUUID: () => clientId
99
+ }
100
+ });
101
+ return engine;
102
+ }
103
+ export {
104
+ COVEO_SHOPIFY_CONFIG_KEY,
105
+ SHOPIFY_COOKIE_KEY,
106
+ buildShopifySearchEngine,
107
+ fetchAppProxyConfig,
108
+ getClientId,
109
+ getShopifyCookie
110
+ };
@@ -0,0 +1,57 @@
1
+ import { buildSearchEngine } from '@coveo/headless';
2
+ import { buildBrowserEnvironment } from '@coveo/relay';
3
+ import { COVEO_SHOPIFY_CONFIG_KEY } from '../constants';
4
+ import { getShopifyCustomEnvironment, } from '../types';
5
+ import { getClientId } from '../utilities/clientid';
6
+ import { publishCustomShopifyEvent } from '../utilities/shopify';
7
+ import { getShopifyCookie } from '../utilities/shopify';
8
+ export { SHOPIFY_COOKIE_KEY, COVEO_SHOPIFY_CONFIG_KEY } from '../constants';
9
+ export * from '@coveo/headless';
10
+ export * from '../utilities';
11
+ /**
12
+ * Builds the search engine for a Shopify store.
13
+ *
14
+ * This function initializes a search engine instance specific to a Shopify store by:
15
+ * - Creating or using an existing browser environment.
16
+ * - Retrieving the "_shopify_y" cookie to confirm it is running in a Shopify context.
17
+ * - Emitting a custom event with the app proxy response to enable tracking and analytics with shopify webpixels.
18
+ * - Storing a client identifier derived from the shop and cookie value in the browser environment's storage.
19
+ * - Building and returning the search engine with the provided options.
20
+ *
21
+ * @remarks
22
+ * The `generateUUID` and `storage` properties are omitted from the custom environment for Shopify
23
+ * to ensure that client IDs are generated consistently across web pixels and storefronts. This is
24
+ * critical for maintaining a unified tracking and personalization experience.
25
+ *
26
+ * @param searchEngineOptions - Options to configure the search engine.
27
+ * @param shopifyCookie - Optional value of the "_shopify_y" cookie. If not provided, it will attempt to retrieve it from the browser's cookies.
28
+ * @param environment - Optional browser environment; if not provided, a default one is created. Mainly useful when not running in a browser environment.
29
+ * @returns The constructed search engine instance.
30
+ * @throws Error if the required "_shopify_y" cookie is not found, ensuring the code runs within a Shopify store.
31
+ */
32
+ export function buildShopifySearchEngine({ searchEngineOptions, environment, shopifyCookie, }) {
33
+ const customEnvironment = environment ?? getShopifyCustomEnvironment(buildBrowserEnvironment());
34
+ const cookie = shopifyCookie || getShopifyCookie();
35
+ if (!searchEngineOptions.configuration.analytics?.trackingId) {
36
+ throw new Error('The configuration for the search engine must include an analytics tracking ID.');
37
+ }
38
+ if (!cookie) {
39
+ throw new Error('Unable to find the _shopify_y cookie. Please ensure you are running this code in a Shopify store.');
40
+ }
41
+ const appProxyResponse = {
42
+ accessToken: searchEngineOptions.configuration.accessToken,
43
+ organizationId: searchEngineOptions.configuration.organizationId,
44
+ environment: searchEngineOptions.configuration.environment,
45
+ trackingId: searchEngineOptions.configuration.analytics.trackingId,
46
+ };
47
+ publishCustomShopifyEvent(COVEO_SHOPIFY_CONFIG_KEY, appProxyResponse);
48
+ const clientId = getClientId(cookie);
49
+ const engine = buildSearchEngine(searchEngineOptions);
50
+ engine.relay.updateConfig({
51
+ environment: {
52
+ ...customEnvironment,
53
+ generateUUID: () => clientId,
54
+ },
55
+ });
56
+ return engine;
57
+ }
@@ -15,23 +15,85 @@
15
15
  * See the License for the specific language governing permissions and
16
16
  * limitations under the License.
17
17
  */
18
+ var __defProp = Object.defineProperty;
19
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
20
+ var __getOwnPropNames = Object.getOwnPropertyNames;
21
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
22
+ var __export = (target, all) => {
23
+ for (var name in all)
24
+ __defProp(target, name, { get: all[name], enumerable: true });
25
+ };
26
+ var __copyProps = (to, from, except, desc) => {
27
+ if (from && typeof from === "object" || typeof from === "function") {
28
+ for (let key of __getOwnPropNames(from))
29
+ if (!__hasOwnProp.call(to, key) && key !== except)
30
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
31
+ }
32
+ return to;
33
+ };
34
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
18
35
 
19
- // src/headless.ts
36
+ // src/headless/index.ts
37
+ var index_exports = {};
38
+ __export(index_exports, {
39
+ COVEO_SHOPIFY_CONFIG_KEY: () => COVEO_SHOPIFY_CONFIG_KEY,
40
+ SHOPIFY_COOKIE_KEY: () => SHOPIFY_COOKIE_KEY,
41
+ buildShopifyCommerceEngine: () => buildShopifyCommerceEngine,
42
+ fetchAppProxyConfig: () => fetchAppProxyConfig,
43
+ getClientId: () => getClientId,
44
+ getShopifyCookie: () => getShopifyCookie
45
+ });
46
+
47
+ // src/headless/commerce.ts
48
+ var commerce_exports = {};
49
+ __export(commerce_exports, {
50
+ COVEO_SHOPIFY_CONFIG_KEY: () => COVEO_SHOPIFY_CONFIG_KEY,
51
+ SHOPIFY_COOKIE_KEY: () => SHOPIFY_COOKIE_KEY,
52
+ buildShopifyCommerceEngine: () => buildShopifyCommerceEngine,
53
+ fetchAppProxyConfig: () => fetchAppProxyConfig,
54
+ getClientId: () => getClientId,
55
+ getShopifyCookie: () => getShopifyCookie
56
+ });
20
57
  import {
21
58
  buildCommerceEngine
22
59
  } from "@coveo/headless/commerce";
23
60
  import { buildBrowserEnvironment } from "@coveo/relay";
24
61
 
25
- // src/utilities.ts
62
+ // src/constants.ts
63
+ var SHOPIFY_COOKIE_KEY = "_shopify_y";
64
+ var COVEO_SHOPIFY_CONFIG_KEY = "coveo_shopify_config";
65
+
66
+ // src/types.ts
67
+ function getShopifyCustomEnvironment(environment) {
68
+ const { storage, generateUUID, ...rest } = environment;
69
+ return rest;
70
+ }
71
+
72
+ // src/utilities/clientid.ts
26
73
  import { v5 } from "uuid";
27
74
  var UUID_NAMESPACE = "c2db3701-991e-424d-b117-03e30d43b651";
28
75
  function getClientId(shopifyCookie) {
29
76
  return v5(shopifyCookie, UUID_NAMESPACE);
30
77
  }
31
78
 
32
- // src/headless.ts
33
- export * from "@coveo/headless/commerce";
34
- var SHOPIFY_COOKIE_KEY = "_shopify_y";
79
+ // src/utilities/shopify.ts
80
+ function getShopifyCookie(name = SHOPIFY_COOKIE_KEY) {
81
+ const match = document.cookie.match(
82
+ new RegExp("(?:^|;\\s*)" + name + "=([^;]*)")
83
+ );
84
+ return match ? decodeURIComponent(match[1]) : null;
85
+ }
86
+ function publishCustomShopifyEvent(key, customData) {
87
+ if (typeof window.Shopify?.analytics?.publish === "function") {
88
+ window.Shopify.analytics.publish(key, customData);
89
+ }
90
+ }
91
+
92
+ // src/headless/commerce.ts
93
+ __reExport(commerce_exports, commerce_star);
94
+ import * as commerce_star from "@coveo/headless/commerce";
95
+
96
+ // src/utilities/app-proxy.ts
35
97
  async function fetchAppProxyConfig({
36
98
  appProxyUrl = "/apps/coveo",
37
99
  marketId
@@ -39,6 +101,8 @@ async function fetchAppProxyConfig({
39
101
  const response = await fetch(`${appProxyUrl}?marketId=${marketId}]`);
40
102
  return response.json();
41
103
  }
104
+
105
+ // src/headless/commerce.ts
42
106
  function buildShopifyCommerceEngine({
43
107
  commerceEngineOptions,
44
108
  shopifyCookie,
@@ -46,11 +110,26 @@ function buildShopifyCommerceEngine({
46
110
  }) {
47
111
  const customEnvironment = environment ?? getShopifyCustomEnvironment(buildBrowserEnvironment());
48
112
  const cookie = shopifyCookie || getShopifyCookie();
113
+ if (!commerceEngineOptions.configuration.analytics.trackingId) {
114
+ throw new Error(
115
+ "The configuration for the commerce engine must include an analytics tracking ID."
116
+ );
117
+ }
49
118
  if (!cookie) {
50
119
  throw new Error(
51
120
  "Unable to find the _shopify_y cookie. Please ensure you are running this code in a Shopify store."
52
121
  );
53
122
  }
123
+ const appProxyResponse = {
124
+ accessToken: commerceEngineOptions.configuration.accessToken,
125
+ organizationId: commerceEngineOptions.configuration.organizationId,
126
+ environment: commerceEngineOptions.configuration.environment,
127
+ trackingId: commerceEngineOptions.configuration.analytics.trackingId
128
+ };
129
+ publishCustomShopifyEvent(
130
+ COVEO_SHOPIFY_CONFIG_KEY,
131
+ appProxyResponse
132
+ );
54
133
  const clientId = getClientId(cookie);
55
134
  const engine = buildCommerceEngine(commerceEngineOptions);
56
135
  engine.relay.updateConfig({
@@ -61,19 +140,12 @@ function buildShopifyCommerceEngine({
61
140
  });
62
141
  return engine;
63
142
  }
64
- function getShopifyCustomEnvironment(environment) {
65
- const { storage, generateUUID, ...rest } = environment;
66
- return rest;
67
- }
68
- function getShopifyCookie(name = SHOPIFY_COOKIE_KEY) {
69
- const match = document.cookie.match(
70
- new RegExp("(?:^|;\\s*)" + name + "=([^;]*)")
71
- );
72
- return match ? decodeURIComponent(match[1]) : null;
73
- }
143
+
144
+ // src/headless/index.ts
145
+ __reExport(index_exports, commerce_exports);
74
146
  export {
147
+ COVEO_SHOPIFY_CONFIG_KEY,
75
148
  SHOPIFY_COOKIE_KEY,
76
- UUID_NAMESPACE,
77
149
  buildShopifyCommerceEngine,
78
150
  fetchAppProxyConfig,
79
151
  getClientId,
@@ -0,0 +1,14 @@
1
+ import { CommerceEngineOptions } from '@coveo/headless/commerce';
2
+ import { CustomEnvironment } from '@coveo/relay';
3
+ export interface AppProxyConfig {
4
+ appProxyUrl?: string;
5
+ marketId: string;
6
+ }
7
+ export interface AppProxyResponse {
8
+ accessToken: string;
9
+ organizationId: string;
10
+ environment: CommerceEngineOptions['configuration']['environment'];
11
+ trackingId: string;
12
+ }
13
+ export type ShopifyCustomEnvironment = Omit<CustomEnvironment, 'storage' | 'generateUUID'>;
14
+ export declare function getShopifyCustomEnvironment(environment: CustomEnvironment): ShopifyCustomEnvironment;
package/dist/types.js ADDED
@@ -0,0 +1,4 @@
1
+ export function getShopifyCustomEnvironment(environment) {
2
+ const { storage, generateUUID, ...rest } = environment;
3
+ return rest;
4
+ }
@@ -0,0 +1,13 @@
1
+ import { AppProxyConfig, AppProxyResponse } from '../types';
2
+ /**
3
+ * Fetches configuration from the app proxy.
4
+ *
5
+ * Performs an HTTP GET request to retrieve the app proxy configuration using the provided marketId.
6
+ * The fetched response is parsed as JSON and returned.
7
+ *
8
+ * @param appProxyUrl - The URL template for the app proxy endpoint. Defaults to '/apps/coveo'.
9
+ * @param marketId - The unique market identifier used as a query parameter.
10
+ * @returns A promise that resolves to an object containing the access token, organization ID,
11
+ * environment, and tracking ID.
12
+ */
13
+ export declare function fetchAppProxyConfig({ appProxyUrl, marketId, }: AppProxyConfig): Promise<AppProxyResponse>;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Fetches configuration from the app proxy.
3
+ *
4
+ * Performs an HTTP GET request to retrieve the app proxy configuration using the provided marketId.
5
+ * The fetched response is parsed as JSON and returned.
6
+ *
7
+ * @param appProxyUrl - The URL template for the app proxy endpoint. Defaults to '/apps/coveo'.
8
+ * @param marketId - The unique market identifier used as a query parameter.
9
+ * @returns A promise that resolves to an object containing the access token, organization ID,
10
+ * environment, and tracking ID.
11
+ */
12
+ export async function fetchAppProxyConfig({ appProxyUrl = '/apps/coveo', marketId, }) {
13
+ const response = await fetch(`${appProxyUrl}?marketId=${marketId}]`);
14
+ return response.json();
15
+ }
@@ -0,0 +1,3 @@
1
+ export { getClientId } from './clientid';
2
+ export { getShopifyCookie } from './shopify';
3
+ export { fetchAppProxyConfig } from './app-proxy';
@@ -0,0 +1,3 @@
1
+ export { getClientId } from './clientid';
2
+ export { getShopifyCookie } from './shopify';
3
+ export { fetchAppProxyConfig } from './app-proxy';
@@ -0,0 +1,22 @@
1
+ export type CustomEvent = Record<string, string>;
2
+ /**
3
+ * Retrieves the value of a specified Shopify cookie by its name.
4
+ *
5
+ * @remarks
6
+ * This function is intended for use in browser environments only, as it relies on the `document.cookie` API.
7
+ * Attempting to use this function in non-browser environments will result in an error or undefined behavior.
8
+ *
9
+ * @param name - The name of the Shopify cookie to retrieve. Defaults to `'_shopify_y'`.
10
+ * @returns The value of the specified cookie, or `null` if the cookie is not found.
11
+ */
12
+ export declare function getShopifyCookie(name?: string): string | null;
13
+ declare global {
14
+ interface Window {
15
+ Shopify?: {
16
+ analytics: {
17
+ publish: (eventName: string, eventData: CustomEvent) => void;
18
+ };
19
+ };
20
+ }
21
+ }
22
+ export declare function publishCustomShopifyEvent(key: string, customData: CustomEvent): void;
@@ -0,0 +1,20 @@
1
+ import { SHOPIFY_COOKIE_KEY } from '../constants';
2
+ /**
3
+ * Retrieves the value of a specified Shopify cookie by its name.
4
+ *
5
+ * @remarks
6
+ * This function is intended for use in browser environments only, as it relies on the `document.cookie` API.
7
+ * Attempting to use this function in non-browser environments will result in an error or undefined behavior.
8
+ *
9
+ * @param name - The name of the Shopify cookie to retrieve. Defaults to `'_shopify_y'`.
10
+ * @returns The value of the specified cookie, or `null` if the cookie is not found.
11
+ */
12
+ export function getShopifyCookie(name = SHOPIFY_COOKIE_KEY) {
13
+ const match = document.cookie.match(new RegExp('(?:^|;\\s*)' + name + '=([^;]*)'));
14
+ return match ? decodeURIComponent(match[1]) : null;
15
+ }
16
+ export function publishCustomShopifyEvent(key, customData) {
17
+ if (typeof window.Shopify?.analytics?.publish === 'function') {
18
+ window.Shopify.analytics.publish(key, customData);
19
+ }
20
+ }
@@ -16,13 +16,34 @@
16
16
  * limitations under the License.
17
17
  */
18
18
 
19
- // src/utilities.ts
19
+ // src/utilities/clientid.ts
20
20
  import { v5 } from "uuid";
21
21
  var UUID_NAMESPACE = "c2db3701-991e-424d-b117-03e30d43b651";
22
22
  function getClientId(shopifyCookie) {
23
23
  return v5(shopifyCookie, UUID_NAMESPACE);
24
24
  }
25
+
26
+ // src/constants.ts
27
+ var SHOPIFY_COOKIE_KEY = "_shopify_y";
28
+
29
+ // src/utilities/shopify.ts
30
+ function getShopifyCookie(name = SHOPIFY_COOKIE_KEY) {
31
+ const match = document.cookie.match(
32
+ new RegExp("(?:^|;\\s*)" + name + "=([^;]*)")
33
+ );
34
+ return match ? decodeURIComponent(match[1]) : null;
35
+ }
36
+
37
+ // src/utilities/app-proxy.ts
38
+ async function fetchAppProxyConfig({
39
+ appProxyUrl = "/apps/coveo",
40
+ marketId
41
+ }) {
42
+ const response = await fetch(`${appProxyUrl}?marketId=${marketId}]`);
43
+ return response.json();
44
+ }
25
45
  export {
26
- UUID_NAMESPACE,
27
- getClientId
46
+ fetchAppProxyConfig,
47
+ getClientId,
48
+ getShopifyCookie
28
49
  };
package/package.json CHANGED
@@ -8,24 +8,34 @@
8
8
  "main": "./dist/headless.esm.js",
9
9
  "module": "./dist/headless.esm.js",
10
10
  "license": "Apache-2.0",
11
- "version": "1.2.2-pre.e593f8f8f7",
11
+ "version": "1.3.0-pre.49914cd105",
12
12
  "files": [
13
13
  "dist/"
14
14
  ],
15
15
  "type": "module",
16
16
  "exports": {
17
17
  ".": {
18
- "types": "./dist/headless.d.ts",
18
+ "types": "./dist/headless/index.d.ts",
19
19
  "import": "./dist/headless.esm.js",
20
20
  "default": "./dist/headless.esm.js"
21
21
  },
22
22
  "./headless": {
23
- "types": "./dist/headless.d.ts",
23
+ "types": "./dist/headless/index.d.ts",
24
24
  "import": "./dist/headless.esm.js",
25
25
  "default": "./dist/headless.esm.js"
26
26
  },
27
+ "./headless/commerce": {
28
+ "types": "./dist/headless/commerce.d.ts",
29
+ "import": "./dist/headless/commerce.esm.js",
30
+ "default": "./dist/headless/commerce.esm.js"
31
+ },
32
+ "./headless/search": {
33
+ "types": "./dist/headless/search.d.ts",
34
+ "import": "./dist/headless/search.esm.js",
35
+ "default": "./dist/headless/search.esm.js"
36
+ },
27
37
  "./utilities": {
28
- "types": "./dist/utilities.d.ts",
38
+ "types": "./dist/utilities/index.d.ts",
29
39
  "import": "./dist/utilities.esm.js",
30
40
  "default": "./dist/utilities.esm.js"
31
41
  }
@@ -46,7 +56,7 @@
46
56
  "vitest": "3.1.2"
47
57
  },
48
58
  "dependencies": {
49
- "@coveo/headless": "3.24.2-pre.e593f8f8f7",
59
+ "@coveo/headless": "3.25.0-pre.49914cd105",
50
60
  "@coveo/relay": "1.2.0",
51
61
  "uuid": "^11.0.0"
52
62
  },
File without changes