@replohq/sdk 2.14.0 → 2.16.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.
@@ -1,4 +1,4 @@
1
- export type ReploScriptType = "GA4" | "GoogleTagManager" | "Meta" | "TikTok" | "Pinterest" | "Reddit" | "Snapchat" | "X" | "Hotjar" | "MicrosoftClarity" | "Contentsquare" | "Segment" | "Northbeam" | "Gorgias" | "Converge" | "Mixpanel" | "HubSpot" | "Attentive" | "Cookiebot" | "snippet" | "custom" | "consentPlatform";
1
+ export type ReploScriptType = "GA4" | "GoogleTagManager" | "Meta" | "TikTok" | "Pinterest" | "Reddit" | "Snapchat" | "X" | "Hotjar" | "MicrosoftClarity" | "Contentsquare" | "Segment" | "Northbeam" | "Gorgias" | "Converge" | "Mixpanel" | "HubSpot" | "Attentive" | "Alia" | "Cookiebot" | "snippet" | "custom" | "consentPlatform";
2
2
  export type ConsentCategory = "necessary" | "analytics" | "marketing" | "preferences" | "sale_of_data";
3
3
  export type ConsentMode = "off" | "simple" | "per-category";
4
4
  export type ScriptTagDescriptor = {
@@ -27,7 +27,7 @@ export type ScriptRuntimeOwner = {
27
27
  };
28
28
  export type MixpanelRegion = "us" | "eu" | "in";
29
29
  export type ReploScriptEntry = {
30
- type: "GoogleTagManager" | "Meta" | "TikTok" | "Pinterest" | "Reddit" | "Snapchat" | "Hotjar" | "MicrosoftClarity" | "Contentsquare" | "Segment" | "Northbeam" | "Gorgias" | "Converge" | "HubSpot" | "Attentive";
30
+ type: "GoogleTagManager" | "Meta" | "TikTok" | "Pinterest" | "Reddit" | "Snapchat" | "Hotjar" | "MicrosoftClarity" | "Contentsquare" | "Segment" | "Northbeam" | "Gorgias" | "Converge" | "HubSpot" | "Attentive" | "Alia";
31
31
  identifier: string;
32
32
  requiredConsent?: ConsentCategory[];
33
33
  } | {
@@ -0,0 +1,7 @@
1
+ export declare const PLACEHOLDER_PRODUCTS_IFRAME_RPC_CHANNEL_ID: "replo:placeholder-products-iframe-rpc";
2
+ export declare const PLACEHOLDER_PRODUCTS_IFRAME_RPC_CHANNEL_VERSION: 3;
3
+ export declare const PLACEHOLDER_HERO_PRODUCT_ID = "f0921037-e530-4e67-a612-d573b7c40b19";
4
+ export declare const PLACEHOLDER_PRODUCT_ID = "c53f98cd-0989-4661-a7c2-a0304d184676";
5
+ export type PlaceholderProductId = typeof PLACEHOLDER_HERO_PRODUCT_ID | typeof PLACEHOLDER_PRODUCT_ID;
6
+ export declare const PLACEHOLDER_PRODUCTS_SOURCE_KEY = "__REPLO_PLACEHOLDER_PRODUCTS__";
7
+ export declare const PLACEHOLDER_PRODUCTS_CHANGE_EVENT = "replo:placeholder-products";
@@ -0,0 +1,8 @@
1
+ var PLACEHOLDER_PRODUCTS_IFRAME_RPC_CHANNEL_ID = "replo:placeholder-products-iframe-rpc";
2
+ var PLACEHOLDER_PRODUCTS_IFRAME_RPC_CHANNEL_VERSION = 3;
3
+ var PLACEHOLDER_HERO_PRODUCT_ID = "f0921037-e530-4e67-a612-d573b7c40b19";
4
+ var PLACEHOLDER_PRODUCT_ID = "c53f98cd-0989-4661-a7c2-a0304d184676";
5
+ var PLACEHOLDER_PRODUCTS_SOURCE_KEY = "__REPLO_PLACEHOLDER_PRODUCTS__";
6
+ var PLACEHOLDER_PRODUCTS_CHANGE_EVENT = "replo:placeholder-products";
7
+
8
+ export { PLACEHOLDER_HERO_PRODUCT_ID, PLACEHOLDER_PRODUCTS_CHANGE_EVENT, PLACEHOLDER_PRODUCTS_IFRAME_RPC_CHANNEL_ID, PLACEHOLDER_PRODUCTS_IFRAME_RPC_CHANNEL_VERSION, PLACEHOLDER_PRODUCTS_SOURCE_KEY, PLACEHOLDER_PRODUCT_ID };
@@ -3,6 +3,7 @@ import React from "react";
3
3
  import { useQueryClient } from "@tanstack/react-query";
4
4
  import { fromMajorUnitsToMinorUnits } from "../../_vendor/schemas/moneyFormat.mjs";
5
5
  import { DATA_LOADER_KEYS } from "../../loaders/loader-keys";
6
+ import { isPlaceholderMerchandiseId } from "../../loaders/placeholder-product";
6
7
  import { useCartInternal } from "../cart-provider";
7
8
  import { toCartError } from "../utils/cart-error";
8
9
  const PRODUCT_LOADER_KEYS = [
@@ -86,9 +87,15 @@ function useAddToCart() {
86
87
  const [isAdding, setIsAdding] = React.useState(false);
87
88
  const addToCart = React.useCallback(
88
89
  async (items, openCartAfterAdd = true) => {
90
+ const buyableItems = items.filter((item) => {
91
+ return !isPlaceholderMerchandiseId(item.merchandiseId);
92
+ });
93
+ if (buyableItems.length === 0) {
94
+ return { adjustments: [], error: null };
95
+ }
89
96
  setIsAdding(true);
90
97
  try {
91
- const cartLines = items.map((item) => {
98
+ const cartLines = buyableItems.map((item) => {
92
99
  const merchandise = item.merchandise ?? findMerchandiseInQueryCache({
93
100
  queryClient,
94
101
  merchandiseId: item.merchandiseId
@@ -185,6 +185,20 @@ gtag('config', '${id}');`
185
185
  attributes: { async: "true" }
186
186
  }
187
187
  ]
188
+ },
189
+ Alia: {
190
+ defaultConsent: ["necessary"],
191
+ buildTags: (id) => [
192
+ {
193
+ kind: "inline",
194
+ body: `window.alia=window.alia||[];(function(){var sent=false;function sync(){var p=window.Replo&&window.Replo.customerPrivacy;if(sent||!p||!p.analyticsProcessingAllowed())return;sent=true;window.alia.push({type:"enableAnalyticsTracking"});}sync();document.addEventListener("visitorConsentCollected",sync);})();`
195
+ },
196
+ {
197
+ kind: "external",
198
+ src: `https://backend.alia-prod.com/public/launcher.js?shopifyUrl=${encodeURIComponent(id)}`,
199
+ attributes: { async: "true" }
200
+ }
201
+ ]
188
202
  }
189
203
  };
190
204
  function isXEventIdForPixel({
@@ -1,4 +1,4 @@
1
- export type ReploScriptType = "GA4" | "GoogleTagManager" | "Meta" | "TikTok" | "Pinterest" | "Reddit" | "Snapchat" | "X" | "Hotjar" | "MicrosoftClarity" | "Contentsquare" | "Segment" | "Northbeam" | "Gorgias" | "Converge" | "HubSpot" | "Mixpanel" | "Attentive" | "Cookiebot" | "snippet" | "custom" | "consentPlatform";
1
+ export type ReploScriptType = "GA4" | "GoogleTagManager" | "Meta" | "TikTok" | "Pinterest" | "Reddit" | "Snapchat" | "X" | "Hotjar" | "MicrosoftClarity" | "Contentsquare" | "Segment" | "Northbeam" | "Gorgias" | "Converge" | "HubSpot" | "Mixpanel" | "Attentive" | "Alia" | "Cookiebot" | "snippet" | "custom" | "consentPlatform";
2
2
  export type ConsentCategory = "necessary" | "analytics" | "marketing" | "preferences" | "sale_of_data";
3
3
  export type ConsentMode = "off" | "simple" | "per-category";
4
4
  declare module "react" {
@@ -36,7 +36,7 @@ export type ScriptRuntimeOwner = {
36
36
  };
37
37
  export type MixpanelRegion = "us" | "eu" | "in";
38
38
  export type ReploScriptEntry = {
39
- type: "GoogleTagManager" | "Meta" | "TikTok" | "Pinterest" | "Reddit" | "Snapchat" | "Hotjar" | "MicrosoftClarity" | "Contentsquare" | "Segment" | "Northbeam" | "Gorgias" | "Converge" | "HubSpot" | "Attentive";
39
+ type: "GoogleTagManager" | "Meta" | "TikTok" | "Pinterest" | "Reddit" | "Snapchat" | "Hotjar" | "MicrosoftClarity" | "Contentsquare" | "Segment" | "Northbeam" | "Gorgias" | "Converge" | "HubSpot" | "Attentive" | "Alia";
40
40
  identifier: string;
41
41
  requiredConsent?: ConsentCategory[];
42
42
  } | {
@@ -1,7 +1,7 @@
1
1
  export const BUILD_METADATA = {
2
2
  "packageName": "@replohq/sdk",
3
- "version": "2.14.0",
3
+ "version": "2.16.0",
4
4
  "branch": "HEAD",
5
- "commit": "06e25b3341d1e79f6171365410c49bee41b1f3e0",
6
- "builtAt": "2026-10-30T20:22:53.823Z"
5
+ "commit": "ace9e163575351a4ad987d0f0427807eaec836ee",
6
+ "builtAt": "2026-10-31T09:51:00.149Z"
7
7
  };
@@ -0,0 +1,24 @@
1
+ import type { PlaceholderProductId } from "../_vendor/schemas/placeholderProductsProtocol";
2
+ import type { FullProduct } from "./loader-schemas";
3
+ import { PLACEHOLDER_PRODUCTS_SOURCE_KEY } from "../_vendor/schemas/placeholderProductsProtocol";
4
+ declare global {
5
+ interface Window {
6
+ __REPLO_PLACEHOLDER_PRODUCTS__?: (card: {
7
+ productId: PlaceholderProductId;
8
+ cardId: string;
9
+ }) => FullProduct | null;
10
+ }
11
+ }
12
+ /** Placeholder IDs name no product, so loaders never fetch them. */
13
+ export declare function isPlaceholderProductId(productId: string | null | undefined): productId is PlaceholderProductId;
14
+ /** A placeholder product's variant IDs start with its placeholder ID, so they never reach a cart. */
15
+ export declare function isPlaceholderMerchandiseId(merchandiseId: string): boolean;
16
+ export type PlaceholderProductSource = NonNullable<Window[typeof PLACEHOLDER_PRODUCTS_SOURCE_KEY]>;
17
+ /** sandbox-runtime's product source (null on the server and on a published site), numbered so each new one is a new key. */
18
+ export declare function usePlaceholderProductSource(): {
19
+ source: ((card: {
20
+ productId: PlaceholderProductId;
21
+ cardId: string;
22
+ }) => FullProduct | null) | null;
23
+ sourceNumber: number;
24
+ };
@@ -0,0 +1,39 @@
1
+ import { useSyncExternalStore } from "react";
2
+ import {
3
+ PLACEHOLDER_HERO_PRODUCT_ID,
4
+ PLACEHOLDER_PRODUCT_ID,
5
+ PLACEHOLDER_PRODUCTS_CHANGE_EVENT,
6
+ PLACEHOLDER_PRODUCTS_SOURCE_KEY
7
+ } from "../_vendor/schemas/placeholderProductsProtocol.mjs";
8
+ function isPlaceholderProductId(productId) {
9
+ return productId === PLACEHOLDER_HERO_PRODUCT_ID || productId === PLACEHOLDER_PRODUCT_ID;
10
+ }
11
+ function isPlaceholderMerchandiseId(merchandiseId) {
12
+ return merchandiseId.startsWith(PLACEHOLDER_HERO_PRODUCT_ID) || merchandiseId.startsWith(PLACEHOLDER_PRODUCT_ID);
13
+ }
14
+ function subscribe(listener) {
15
+ window.addEventListener(PLACEHOLDER_PRODUCTS_CHANGE_EVENT, listener);
16
+ return () => {
17
+ window.removeEventListener(PLACEHOLDER_PRODUCTS_CHANGE_EVENT, listener);
18
+ };
19
+ }
20
+ let sourceCount = 0;
21
+ const sourceNumbers = /* @__PURE__ */ new WeakMap();
22
+ function getSourceNumber(source) {
23
+ const sourceNumber = sourceNumbers.get(source) ?? ++sourceCount;
24
+ sourceNumbers.set(source, sourceNumber);
25
+ return sourceNumber;
26
+ }
27
+ function usePlaceholderProductSource() {
28
+ const source = useSyncExternalStore(
29
+ subscribe,
30
+ () => window[PLACEHOLDER_PRODUCTS_SOURCE_KEY] ?? null,
31
+ () => null
32
+ );
33
+ return { source, sourceNumber: source ? getSourceNumber(source) : 0 };
34
+ }
35
+ export {
36
+ isPlaceholderMerchandiseId,
37
+ isPlaceholderProductId,
38
+ usePlaceholderProductSource
39
+ };
@@ -1,9 +1,13 @@
1
1
  "use client";
2
2
  import { Fragment, jsx } from "react/jsx-runtime";
3
- import { Suspense } from "react";
3
+ import { Suspense, useId } from "react";
4
4
  import { useSuspenseQuery } from "@tanstack/react-query";
5
5
  import { invokeLoader } from "./invoke-loader";
6
6
  import { LoaderErrorBoundary } from "./loader-error-boundary";
7
+ import {
8
+ isPlaceholderProductId,
9
+ usePlaceholderProductSource
10
+ } from "./placeholder-product";
7
11
  import { useReportPreviewPlaceholderRender } from "./preview-placeholder";
8
12
  import { buildProductLoaderArgs } from "./product-loader-args";
9
13
  function ProductLoaderInner({
@@ -20,6 +24,39 @@ function ProductLoaderInner({
20
24
  useReportPreviewPlaceholderRender(queryResult.data);
21
25
  return /* @__PURE__ */ jsx(Fragment, { children: children(queryResult.data) });
22
26
  }
27
+ function PlaceholderProductCard({
28
+ getProduct,
29
+ card,
30
+ fallback,
31
+ children
32
+ }) {
33
+ const product = getProduct?.(card) ?? null;
34
+ return /* @__PURE__ */ jsx(Fragment, { children: product ? children(product) : fallback });
35
+ }
36
+ function PlaceholderProductLoader({
37
+ productId,
38
+ fallback,
39
+ children
40
+ }) {
41
+ const cardId = useId();
42
+ const { source, sourceNumber } = usePlaceholderProductSource();
43
+ return /* @__PURE__ */ jsx(
44
+ LoaderErrorBoundary,
45
+ {
46
+ fallback,
47
+ resetKey: `placeholder:${productId}:${sourceNumber}`,
48
+ children: /* @__PURE__ */ jsx(
49
+ PlaceholderProductCard,
50
+ {
51
+ getProduct: source,
52
+ card: { productId, cardId },
53
+ fallback,
54
+ children
55
+ }
56
+ )
57
+ }
58
+ );
59
+ }
23
60
  function ProductLoader({
24
61
  loaderKey,
25
62
  handle,
@@ -32,6 +69,16 @@ function ProductLoader({
32
69
  fallback,
33
70
  loadingFallback = fallback
34
71
  }) {
72
+ if (isPlaceholderProductId(productId)) {
73
+ return /* @__PURE__ */ jsx(
74
+ PlaceholderProductLoader,
75
+ {
76
+ productId,
77
+ fallback: fallback ?? null,
78
+ children
79
+ }
80
+ );
81
+ }
35
82
  const args = buildProductLoaderArgs({
36
83
  handle,
37
84
  productId,
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@replohq/sdk",
3
- "version": "2.14.0",
3
+ "version": "2.16.0",
4
4
  "reploBuild": {
5
5
  "packageName": "@replohq/sdk",
6
- "version": "2.14.0",
6
+ "version": "2.16.0",
7
7
  "branch": "HEAD",
8
- "commit": "06e25b3341d1e79f6171365410c49bee41b1f3e0",
9
- "builtAt": "2026-10-30T20:22:53.823Z"
8
+ "commit": "ace9e163575351a4ad987d0f0427807eaec836ee",
9
+ "builtAt": "2026-10-31T09:51:00.149Z"
10
10
  },
11
11
  "description": "Replo SDK — cart, analytics, and data loaders for agent-built Next.js sites.",
12
12
  "license": "SEE LICENSE IN LICENSE",