@shopify/hydrogen-react 2025.4.0 → 2025.4.1
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/browser-dev/ShopifyProvider.mjs +18 -1
- package/dist/browser-dev/ShopifyProvider.mjs.map +1 -1
- package/dist/browser-dev/analytics.mjs +4 -5
- package/dist/browser-dev/analytics.mjs.map +1 -1
- package/dist/browser-dev/cart-hooks.mjs +25 -7
- package/dist/browser-dev/cart-hooks.mjs.map +1 -1
- package/dist/browser-dev/cookies-utils.mjs +4 -4
- package/dist/browser-dev/cookies-utils.mjs.map +1 -1
- package/dist/browser-dev/index.mjs +4 -0
- package/dist/browser-dev/index.mjs.map +1 -1
- package/dist/browser-dev/packages/hydrogen-react/package.json.mjs +1 -1
- package/dist/browser-dev/tracking-utils.mjs +88 -0
- package/dist/browser-dev/tracking-utils.mjs.map +1 -0
- package/dist/browser-dev/useShopifyCookies.mjs +96 -9
- package/dist/browser-dev/useShopifyCookies.mjs.map +1 -1
- package/dist/browser-prod/ShopifyProvider.mjs +18 -1
- package/dist/browser-prod/ShopifyProvider.mjs.map +1 -1
- package/dist/browser-prod/analytics.mjs +4 -5
- package/dist/browser-prod/analytics.mjs.map +1 -1
- package/dist/browser-prod/cart-hooks.mjs +25 -7
- package/dist/browser-prod/cart-hooks.mjs.map +1 -1
- package/dist/browser-prod/cookies-utils.mjs +4 -4
- package/dist/browser-prod/cookies-utils.mjs.map +1 -1
- package/dist/browser-prod/index.mjs +4 -0
- package/dist/browser-prod/index.mjs.map +1 -1
- package/dist/browser-prod/packages/hydrogen-react/package.json.mjs +1 -1
- package/dist/browser-prod/tracking-utils.mjs +88 -0
- package/dist/browser-prod/tracking-utils.mjs.map +1 -0
- package/dist/browser-prod/useShopifyCookies.mjs +96 -9
- package/dist/browser-prod/useShopifyCookies.mjs.map +1 -1
- package/dist/node-dev/ShopifyProvider.js +18 -1
- package/dist/node-dev/ShopifyProvider.js.map +1 -1
- package/dist/node-dev/ShopifyProvider.mjs +18 -1
- package/dist/node-dev/ShopifyProvider.mjs.map +1 -1
- package/dist/node-dev/analytics.js +4 -5
- package/dist/node-dev/analytics.js.map +1 -1
- package/dist/node-dev/analytics.mjs +4 -5
- package/dist/node-dev/analytics.mjs.map +1 -1
- package/dist/node-dev/cart-hooks.js +24 -6
- package/dist/node-dev/cart-hooks.js.map +1 -1
- package/dist/node-dev/cart-hooks.mjs +25 -7
- package/dist/node-dev/cart-hooks.mjs.map +1 -1
- package/dist/node-dev/cookies-utils.js +4 -4
- package/dist/node-dev/cookies-utils.js.map +1 -1
- package/dist/node-dev/cookies-utils.mjs +4 -4
- package/dist/node-dev/cookies-utils.mjs.map +1 -1
- package/dist/node-dev/index.js +4 -0
- package/dist/node-dev/index.js.map +1 -1
- package/dist/node-dev/index.mjs +4 -0
- package/dist/node-dev/index.mjs.map +1 -1
- package/dist/node-dev/packages/hydrogen-react/package.json.js +1 -1
- package/dist/node-dev/packages/hydrogen-react/package.json.mjs +1 -1
- package/dist/node-dev/tracking-utils.js +88 -0
- package/dist/node-dev/tracking-utils.js.map +1 -0
- package/dist/node-dev/tracking-utils.mjs +88 -0
- package/dist/node-dev/tracking-utils.mjs.map +1 -0
- package/dist/node-dev/useShopifyCookies.js +94 -7
- package/dist/node-dev/useShopifyCookies.js.map +1 -1
- package/dist/node-dev/useShopifyCookies.mjs +96 -9
- package/dist/node-dev/useShopifyCookies.mjs.map +1 -1
- package/dist/node-prod/ShopifyProvider.js +18 -1
- package/dist/node-prod/ShopifyProvider.js.map +1 -1
- package/dist/node-prod/ShopifyProvider.mjs +18 -1
- package/dist/node-prod/ShopifyProvider.mjs.map +1 -1
- package/dist/node-prod/analytics.js +4 -5
- package/dist/node-prod/analytics.js.map +1 -1
- package/dist/node-prod/analytics.mjs +4 -5
- package/dist/node-prod/analytics.mjs.map +1 -1
- package/dist/node-prod/cart-hooks.js +24 -6
- package/dist/node-prod/cart-hooks.js.map +1 -1
- package/dist/node-prod/cart-hooks.mjs +25 -7
- package/dist/node-prod/cart-hooks.mjs.map +1 -1
- package/dist/node-prod/cookies-utils.js +4 -4
- package/dist/node-prod/cookies-utils.js.map +1 -1
- package/dist/node-prod/cookies-utils.mjs +4 -4
- package/dist/node-prod/cookies-utils.mjs.map +1 -1
- package/dist/node-prod/index.js +4 -0
- package/dist/node-prod/index.js.map +1 -1
- package/dist/node-prod/index.mjs +4 -0
- package/dist/node-prod/index.mjs.map +1 -1
- package/dist/node-prod/packages/hydrogen-react/package.json.js +1 -1
- package/dist/node-prod/packages/hydrogen-react/package.json.mjs +1 -1
- package/dist/node-prod/tracking-utils.js +88 -0
- package/dist/node-prod/tracking-utils.js.map +1 -0
- package/dist/node-prod/tracking-utils.mjs +88 -0
- package/dist/node-prod/tracking-utils.mjs.map +1 -0
- package/dist/node-prod/useShopifyCookies.js +94 -7
- package/dist/node-prod/useShopifyCookies.js.map +1 -1
- package/dist/node-prod/useShopifyCookies.mjs +96 -9
- package/dist/node-prod/useShopifyCookies.mjs.map +1 -1
- package/dist/types/ShopifyProvider.d.ts +5 -0
- package/dist/types/cookies-utils.d.ts +4 -0
- package/dist/types/index.d.cts +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/tracking-utils.d.ts +22 -0
- package/dist/types/useShopifyCookies.d.ts +28 -2
- package/dist/umd/hydrogen-react.dev.js +271 -89
- package/dist/umd/hydrogen-react.dev.js.map +1 -1
- package/dist/umd/hydrogen-react.prod.js +18 -18
- package/dist/umd/hydrogen-react.prod.js.map +1 -1
- package/package.json +1 -1
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
return t2 === n2;
|
|
70
70
|
};
|
|
71
71
|
}
|
|
72
|
-
function u
|
|
72
|
+
function u(t2) {
|
|
73
73
|
return "string" == typeof t2 ? { type: t2 } : t2;
|
|
74
74
|
}
|
|
75
75
|
function c(t2, n2) {
|
|
@@ -93,7 +93,7 @@
|
|
|
93
93
|
var s2 = t(f(r(n2.states[n2.initial].entry).map(function(t2) {
|
|
94
94
|
return o(t2, i2.actions);
|
|
95
95
|
}), n2.context, e), 2), l2 = s2[0], v2 = s2[1], y = { config: n2, _options: i2, initialState: { value: n2.initial, actions: l2, context: v2, matches: a(n2.initial) }, transition: function(e2, i3) {
|
|
96
|
-
var s3, l3, v3 = "string" == typeof e2 ? { value: e2, context: n2.context } : e2, p = v3.value,
|
|
96
|
+
var s3, l3, v3 = "string" == typeof e2 ? { value: e2, context: n2.context } : e2, p = v3.value, g = v3.context, d = u(i3), x = n2.states[p];
|
|
97
97
|
if (x.on) {
|
|
98
98
|
var m = r(x.on[d.type]);
|
|
99
99
|
try {
|
|
@@ -106,16 +106,16 @@
|
|
|
106
106
|
throw new TypeError(n3 ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
107
107
|
}(m), b = h.next(); !b.done; b = h.next()) {
|
|
108
108
|
var S = b.value;
|
|
109
|
-
if (void 0 === S) return c(p,
|
|
109
|
+
if (void 0 === S) return c(p, g);
|
|
110
110
|
var w = "string" == typeof S ? { target: S } : S, j = w.target, E = w.actions, R = void 0 === E ? [] : E, N = w.cond, O = void 0 === N ? function() {
|
|
111
111
|
return true;
|
|
112
112
|
} : N, _ = void 0 === j, k = null != j ? j : p, T = n2.states[k];
|
|
113
|
-
if (O(
|
|
113
|
+
if (O(g, d)) {
|
|
114
114
|
var q = t(f((_ ? r(R) : [].concat(x.exit, R, T.entry).filter(function(t2) {
|
|
115
115
|
return t2;
|
|
116
116
|
})).map(function(t2) {
|
|
117
117
|
return o(t2, y._options.actions);
|
|
118
|
-
}),
|
|
118
|
+
}), g, d), 3), z = q[0], A = q[1], B = q[2], C = null != j ? j : p;
|
|
119
119
|
return { value: C, context: A, actions: z, changed: j !== p || z.length > 0 || B, matches: a(C) };
|
|
120
120
|
}
|
|
121
121
|
}
|
|
@@ -129,7 +129,7 @@
|
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
|
-
return c(p,
|
|
132
|
+
return c(p, g);
|
|
133
133
|
} };
|
|
134
134
|
return y;
|
|
135
135
|
}
|
|
@@ -141,7 +141,7 @@
|
|
|
141
141
|
};
|
|
142
142
|
function v(t2) {
|
|
143
143
|
var r2 = t2.initialState, i2 = n.NotStarted, o2 = /* @__PURE__ */ new Set(), c2 = { _machine: t2, send: function(e2) {
|
|
144
|
-
i2 === n.Running && (r2 = t2.transition(r2, e2), l$1(r2, u
|
|
144
|
+
i2 === n.Running && (r2 = t2.transition(r2, e2), l$1(r2, u(e2)), o2.forEach(function(t3) {
|
|
145
145
|
return t3(r2);
|
|
146
146
|
}));
|
|
147
147
|
}, subscribe: function(t3) {
|
|
@@ -929,6 +929,21 @@ Refer to the authentication https://shopify.dev/api/storefront#authentication do
|
|
|
929
929
|
const ShopifyContext = React$1.createContext(
|
|
930
930
|
defaultShopifyContext
|
|
931
931
|
);
|
|
932
|
+
function isSfapiProxyEnabled() {
|
|
933
|
+
var _a, _b, _c;
|
|
934
|
+
if (typeof window === "undefined") return false;
|
|
935
|
+
try {
|
|
936
|
+
const navigationEntry = (_b = (_a = window.performance) == null ? void 0 : _a.getEntriesByType) == null ? void 0 : _b.call(
|
|
937
|
+
_a,
|
|
938
|
+
"navigation"
|
|
939
|
+
)[0];
|
|
940
|
+
return !!((_c = navigationEntry == null ? void 0 : navigationEntry.serverTiming) == null ? void 0 : _c.some(
|
|
941
|
+
(entry) => entry.name === "_sfapi_proxy"
|
|
942
|
+
));
|
|
943
|
+
} catch (e2) {
|
|
944
|
+
return false;
|
|
945
|
+
}
|
|
946
|
+
}
|
|
932
947
|
function ShopifyProvider({
|
|
933
948
|
children,
|
|
934
949
|
...shopifyConfig
|
|
@@ -944,12 +959,14 @@ Refer to the authentication https://shopify.dev/api/storefront#authentication do
|
|
|
944
959
|
);
|
|
945
960
|
}
|
|
946
961
|
const finalConfig = React$1.useMemo(() => {
|
|
962
|
+
const sameDomainForStorefrontApi = shopifyConfig.sameDomainForStorefrontApi ?? isSfapiProxyEnabled();
|
|
947
963
|
function getShopifyDomain(overrideProps) {
|
|
948
964
|
const domain = (overrideProps == null ? void 0 : overrideProps.storeDomain) ?? shopifyConfig.storeDomain;
|
|
949
965
|
return domain.includes("://") ? domain : `https://${domain}`;
|
|
950
966
|
}
|
|
951
967
|
return {
|
|
952
968
|
...shopifyConfig,
|
|
969
|
+
sameDomainForStorefrontApi,
|
|
953
970
|
getPublicTokenHeaders(overrideProps) {
|
|
954
971
|
return getPublicTokenHeadersRaw(
|
|
955
972
|
overrideProps.contentType,
|
|
@@ -959,7 +976,7 @@ Refer to the authentication https://shopify.dev/api/storefront#authentication do
|
|
|
959
976
|
},
|
|
960
977
|
getShopifyDomain,
|
|
961
978
|
getStorefrontApiUrl(overrideProps) {
|
|
962
|
-
const finalDomainUrl = getShopifyDomain({
|
|
979
|
+
const finalDomainUrl = sameDomainForStorefrontApi && typeof window !== "undefined" ? window.location.origin : getShopifyDomain({
|
|
963
980
|
storeDomain: (overrideProps == null ? void 0 : overrideProps.storeDomain) ?? shopifyConfig.storeDomain
|
|
964
981
|
});
|
|
965
982
|
return `${finalDomainUrl}${finalDomainUrl.endsWith("/") ? "" : "/"}api/${(overrideProps == null ? void 0 : overrideProps.storefrontApiVersion) ?? shopifyConfig.storefrontApiVersion}/graphql.json`;
|
|
@@ -981,77 +998,94 @@ Refer to the authentication https://shopify.dev/api/storefront#authentication do
|
|
|
981
998
|
const SHOPIFY_STOREFRONT_S_HEADER = "Shopify-Storefront-S";
|
|
982
999
|
const SHOPIFY_Y = "_shopify_y";
|
|
983
1000
|
const SHOPIFY_S = "_shopify_s";
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
"
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
+
const SHOPIFY_VISIT_TOKEN_HEADER = "X-Shopify-VisitToken";
|
|
1002
|
+
const SHOPIFY_UNIQUE_TOKEN_HEADER = "X-Shopify-UniqueToken";
|
|
1003
|
+
const cachedTrackingValues = { current: null };
|
|
1004
|
+
function getTrackingValues(cookieString) {
|
|
1005
|
+
var _a, _b, _c;
|
|
1006
|
+
let trackingValues;
|
|
1007
|
+
if (typeof window !== "undefined" && typeof window.performance !== "undefined") {
|
|
1008
|
+
try {
|
|
1009
|
+
const resourceRE = /^https?:\/\/([^/]+)(\/api\/(?:unstable|2\d{3}-\d{2})\/graphql\.json(?=$|\?))?/;
|
|
1010
|
+
const entries = performance.getEntriesByType(
|
|
1011
|
+
"resource"
|
|
1012
|
+
);
|
|
1013
|
+
let matchedValues;
|
|
1014
|
+
for (let i2 = entries.length - 1; i2 >= 0; i2--) {
|
|
1015
|
+
const entry = entries[i2];
|
|
1016
|
+
if (entry.initiatorType !== "fetch") continue;
|
|
1017
|
+
const currentHost = window.location.host;
|
|
1018
|
+
const match = entry.name.match(resourceRE);
|
|
1019
|
+
if (!match) continue;
|
|
1020
|
+
const [, matchedHost, sfapiPath] = match;
|
|
1021
|
+
const isMatch = (
|
|
1022
|
+
// Same origin (exact host match)
|
|
1023
|
+
matchedHost === currentHost || // Subdomain with SFAPI path
|
|
1024
|
+
sfapiPath && (matchedHost == null ? void 0 : matchedHost.endsWith(`.${currentHost}`))
|
|
1025
|
+
);
|
|
1026
|
+
if (isMatch) {
|
|
1027
|
+
const values = extractFromPerformanceEntry(entry);
|
|
1028
|
+
if (values) {
|
|
1029
|
+
matchedValues = values;
|
|
1030
|
+
break;
|
|
1031
|
+
}
|
|
1001
1032
|
}
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
hash = tokenHash.replace(/[x]/g, (c2) => {
|
|
1020
|
-
const r2 = randomValuesArray[i2] % 16;
|
|
1021
|
-
const v2 = c2 === "x" ? r2 : r2 & 3 | 8;
|
|
1022
|
-
i2++;
|
|
1023
|
-
return v2.toString(16);
|
|
1024
|
-
}).toUpperCase();
|
|
1025
|
-
} catch (err) {
|
|
1026
|
-
hash = tokenHash.replace(/[x]/g, (c2) => {
|
|
1027
|
-
const r2 = Math.random() * 16 | 0;
|
|
1028
|
-
const v2 = c2 === "x" ? r2 : r2 & 3 | 8;
|
|
1029
|
-
return v2.toString(16);
|
|
1030
|
-
}).toUpperCase();
|
|
1033
|
+
}
|
|
1034
|
+
if (matchedValues) {
|
|
1035
|
+
trackingValues = matchedValues;
|
|
1036
|
+
}
|
|
1037
|
+
if (trackingValues) {
|
|
1038
|
+
cachedTrackingValues.current = trackingValues;
|
|
1039
|
+
} else if (cachedTrackingValues.current) {
|
|
1040
|
+
trackingValues = cachedTrackingValues.current;
|
|
1041
|
+
}
|
|
1042
|
+
if (!trackingValues) {
|
|
1043
|
+
const navigationEntries = performance.getEntriesByType(
|
|
1044
|
+
"navigation"
|
|
1045
|
+
)[0];
|
|
1046
|
+
trackingValues = extractFromPerformanceEntry(navigationEntries, false);
|
|
1047
|
+
}
|
|
1048
|
+
} catch {
|
|
1049
|
+
}
|
|
1031
1050
|
}
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
perfNumber = performance.now() >>> 0;
|
|
1040
|
-
} catch (err) {
|
|
1041
|
-
perfNumber = 0;
|
|
1051
|
+
if (!trackingValues) {
|
|
1052
|
+
const cookie = typeof cookieString === "string" ? cookieString : typeof document !== "undefined" ? document.cookie : "";
|
|
1053
|
+
trackingValues = {
|
|
1054
|
+
uniqueToken: ((_a = cookie.match(/\b_shopify_y=([^;]+)/)) == null ? void 0 : _a[1]) || "",
|
|
1055
|
+
visitToken: ((_b = cookie.match(/\b_shopify_s=([^;]+)/)) == null ? void 0 : _b[1]) || "",
|
|
1056
|
+
consent: ((_c = cookie.match(/\b_tracking_consent=([^;]+)/)) == null ? void 0 : _c[1]) || ""
|
|
1057
|
+
};
|
|
1042
1058
|
}
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1059
|
+
return trackingValues;
|
|
1060
|
+
}
|
|
1061
|
+
function extractFromPerformanceEntry(entry, isConsentRequired = true) {
|
|
1062
|
+
let uniqueToken = "";
|
|
1063
|
+
let visitToken = "";
|
|
1064
|
+
let consent = "";
|
|
1065
|
+
const serverTiming = entry.serverTiming;
|
|
1066
|
+
if (serverTiming && serverTiming.length >= 3) {
|
|
1067
|
+
for (let i2 = serverTiming.length - 1; i2 >= 0; i2--) {
|
|
1068
|
+
const { name, description } = serverTiming[i2];
|
|
1069
|
+
if (!name || !description) continue;
|
|
1070
|
+
if (name === "_y") {
|
|
1071
|
+
uniqueToken = description;
|
|
1072
|
+
} else if (name === "_s") {
|
|
1073
|
+
visitToken = description;
|
|
1074
|
+
} else if (name === "_cmp") {
|
|
1075
|
+
consent = description;
|
|
1076
|
+
}
|
|
1077
|
+
if (uniqueToken && visitToken && consent) break;
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
return uniqueToken && visitToken && (isConsentRequired ? consent : true) ? { uniqueToken, visitToken, consent } : void 0;
|
|
1052
1081
|
}
|
|
1053
1082
|
function useCartFetch() {
|
|
1054
|
-
const {
|
|
1083
|
+
const {
|
|
1084
|
+
storefrontId,
|
|
1085
|
+
getPublicTokenHeaders,
|
|
1086
|
+
getStorefrontApiUrl,
|
|
1087
|
+
sameDomainForStorefrontApi
|
|
1088
|
+
} = useShop();
|
|
1055
1089
|
return React$1.useCallback(
|
|
1056
1090
|
({
|
|
1057
1091
|
query,
|
|
@@ -1061,9 +1095,17 @@ Refer to the authentication https://shopify.dev/api/storefront#authentication do
|
|
|
1061
1095
|
if (storefrontId) {
|
|
1062
1096
|
headers[SHOPIFY_STOREFRONT_ID_HEADER] = storefrontId;
|
|
1063
1097
|
}
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1098
|
+
if (!sameDomainForStorefrontApi) {
|
|
1099
|
+
const { uniqueToken, visitToken } = getTrackingValues();
|
|
1100
|
+
if (uniqueToken) {
|
|
1101
|
+
headers[SHOPIFY_STOREFRONT_Y_HEADER] = uniqueToken;
|
|
1102
|
+
headers[SHOPIFY_UNIQUE_TOKEN_HEADER] = uniqueToken;
|
|
1103
|
+
}
|
|
1104
|
+
if (visitToken) {
|
|
1105
|
+
headers[SHOPIFY_STOREFRONT_S_HEADER] = visitToken;
|
|
1106
|
+
headers[SHOPIFY_VISIT_TOKEN_HEADER] = visitToken;
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1067
1109
|
return fetch(getStorefrontApiUrl(), {
|
|
1068
1110
|
method: "POST",
|
|
1069
1111
|
headers,
|
|
@@ -1081,7 +1123,12 @@ Refer to the authentication https://shopify.dev/api/storefront#authentication do
|
|
|
1081
1123
|
};
|
|
1082
1124
|
});
|
|
1083
1125
|
},
|
|
1084
|
-
[
|
|
1126
|
+
[
|
|
1127
|
+
getPublicTokenHeaders,
|
|
1128
|
+
storefrontId,
|
|
1129
|
+
getStorefrontApiUrl,
|
|
1130
|
+
sameDomainForStorefrontApi
|
|
1131
|
+
]
|
|
1085
1132
|
);
|
|
1086
1133
|
}
|
|
1087
1134
|
function useCartActions({
|
|
@@ -2358,6 +2405,48 @@ Refer to the authentication https://shopify.dev/api/storefront#authentication do
|
|
|
2358
2405
|
}
|
|
2359
2406
|
return false;
|
|
2360
2407
|
}
|
|
2408
|
+
const tokenHash = "xxxx-4xxx-xxxx-xxxxxxxxxxxx";
|
|
2409
|
+
function buildUUID() {
|
|
2410
|
+
let hash = "";
|
|
2411
|
+
try {
|
|
2412
|
+
const crypto = window.crypto;
|
|
2413
|
+
const randomValuesArray = new Uint16Array(31);
|
|
2414
|
+
crypto.getRandomValues(randomValuesArray);
|
|
2415
|
+
let i2 = 0;
|
|
2416
|
+
hash = tokenHash.replace(/[x]/g, (c2) => {
|
|
2417
|
+
const r2 = randomValuesArray[i2] % 16;
|
|
2418
|
+
const v2 = c2 === "x" ? r2 : r2 & 3 | 8;
|
|
2419
|
+
i2++;
|
|
2420
|
+
return v2.toString(16);
|
|
2421
|
+
}).toUpperCase();
|
|
2422
|
+
} catch (err) {
|
|
2423
|
+
hash = tokenHash.replace(/[x]/g, (c2) => {
|
|
2424
|
+
const r2 = Math.random() * 16 | 0;
|
|
2425
|
+
const v2 = c2 === "x" ? r2 : r2 & 3 | 8;
|
|
2426
|
+
return v2.toString(16);
|
|
2427
|
+
}).toUpperCase();
|
|
2428
|
+
}
|
|
2429
|
+
return `${hexTime()}-${hash}`;
|
|
2430
|
+
}
|
|
2431
|
+
function hexTime() {
|
|
2432
|
+
let dateNumber = 0;
|
|
2433
|
+
let perfNumber = 0;
|
|
2434
|
+
dateNumber = (/* @__PURE__ */ new Date()).getTime() >>> 0;
|
|
2435
|
+
try {
|
|
2436
|
+
perfNumber = performance.now() >>> 0;
|
|
2437
|
+
} catch (err) {
|
|
2438
|
+
perfNumber = 0;
|
|
2439
|
+
}
|
|
2440
|
+
const output = Math.abs(dateNumber + perfNumber).toString(16).toLowerCase();
|
|
2441
|
+
return output.padStart(8, "0");
|
|
2442
|
+
}
|
|
2443
|
+
function getShopifyCookies(cookies) {
|
|
2444
|
+
const trackingValues = getTrackingValues(cookies);
|
|
2445
|
+
return {
|
|
2446
|
+
[SHOPIFY_Y]: trackingValues.uniqueToken,
|
|
2447
|
+
[SHOPIFY_S]: trackingValues.visitToken
|
|
2448
|
+
};
|
|
2449
|
+
}
|
|
2361
2450
|
const SCHEMA_ID$1 = "trekkie_storefront_page_view/1.4";
|
|
2362
2451
|
const OXYGEN_DOMAIN = "myshopify.dev";
|
|
2363
2452
|
function pageView$1(payload) {
|
|
@@ -2409,7 +2498,7 @@ Refer to the authentication https://shopify.dev/api/storefront#authentication do
|
|
|
2409
2498
|
}
|
|
2410
2499
|
return false;
|
|
2411
2500
|
}
|
|
2412
|
-
const version = "2025.4.
|
|
2501
|
+
const version = "2025.4.1";
|
|
2413
2502
|
const SCHEMA_ID = "custom_storefront_customer_tracking/1.2";
|
|
2414
2503
|
const PAGE_RENDERED_EVENT_NAME = "page_rendered";
|
|
2415
2504
|
const COLLECTION_PAGE_RENDERED_EVENT_NAME = "collection_page_rendered";
|
|
@@ -2727,10 +2816,10 @@ Refer to the authentication https://shopify.dev/api/storefront#authentication do
|
|
|
2727
2816
|
};
|
|
2728
2817
|
}
|
|
2729
2818
|
const [navigationType, navigationApi] = getNavigationType();
|
|
2730
|
-
const
|
|
2819
|
+
const trackingValues = getTrackingValues();
|
|
2731
2820
|
return {
|
|
2732
|
-
uniqueToken:
|
|
2733
|
-
visitToken:
|
|
2821
|
+
uniqueToken: trackingValues.uniqueToken,
|
|
2822
|
+
visitToken: trackingValues.visitToken,
|
|
2734
2823
|
url: location.href,
|
|
2735
2824
|
path: location.pathname,
|
|
2736
2825
|
search: location.search,
|
|
@@ -4557,17 +4646,29 @@ Refer to the authentication https://shopify.dev/api/storefront#authentication do
|
|
|
4557
4646
|
}, [JSON.stringify(selectedOptions)]);
|
|
4558
4647
|
return null;
|
|
4559
4648
|
}
|
|
4649
|
+
function l(a2, r2, e2 = {}) {
|
|
4650
|
+
let t2 = a2 + "=" + encodeURIComponent(r2);
|
|
4651
|
+
return e2.expires && (t2 += "; Expires=" + new Date(e2.expires).toUTCString()), e2.maxage != null && e2.maxage >= 0 && (t2 += "; Max-Age=" + (e2.maxage | 0)), e2.domain && (t2 += "; Domain=" + e2.domain), e2.path && (t2 += "; Path=" + e2.path), e2.samesite && (t2 += "; SameSite=" + e2.samesite), (e2.secure || e2.samesite === "None") && (t2 += "; Secure"), e2.httponly && (t2 += "; HttpOnly"), t2;
|
|
4652
|
+
}
|
|
4560
4653
|
const longTermLength = 60 * 60 * 24 * 360 * 1;
|
|
4561
4654
|
const shortTermLength = 60 * 30;
|
|
4562
4655
|
function useShopifyCookies(options) {
|
|
4563
4656
|
const {
|
|
4564
|
-
hasUserConsent
|
|
4657
|
+
hasUserConsent,
|
|
4565
4658
|
domain = "",
|
|
4566
|
-
checkoutDomain = ""
|
|
4659
|
+
checkoutDomain = "",
|
|
4660
|
+
storefrontAccessToken,
|
|
4661
|
+
fetchTrackingValues,
|
|
4662
|
+
ignoreDeprecatedCookies = false
|
|
4567
4663
|
} = options || {};
|
|
4664
|
+
const coreCookiesReady = useCoreShopifyCookies({
|
|
4665
|
+
storefrontAccessToken,
|
|
4666
|
+
fetchTrackingValues,
|
|
4667
|
+
checkoutDomain
|
|
4668
|
+
});
|
|
4568
4669
|
React$1.useEffect(() => {
|
|
4569
|
-
|
|
4570
|
-
let currentDomain = domain || window.
|
|
4670
|
+
if (ignoreDeprecatedCookies || !coreCookiesReady) return;
|
|
4671
|
+
let currentDomain = domain || window.location.host;
|
|
4571
4672
|
if (checkoutDomain) {
|
|
4572
4673
|
const checkoutDomainParts = checkoutDomain.split(".").reverse();
|
|
4573
4674
|
const currentDomainParts = currentDomain.split(".").reverse();
|
|
@@ -4582,15 +4683,19 @@ Refer to the authentication https://shopify.dev/api/storefront#authentication do
|
|
|
4582
4683
|
if (/^localhost/.test(currentDomain)) currentDomain = "";
|
|
4583
4684
|
const domainWithLeadingDot = currentDomain ? /^\./.test(currentDomain) ? currentDomain : `.${currentDomain}` : "";
|
|
4584
4685
|
if (hasUserConsent) {
|
|
4686
|
+
const trackingValues = getTrackingValues();
|
|
4687
|
+
if ((trackingValues.uniqueToken || trackingValues.visitToken || "").startsWith("00000000-")) {
|
|
4688
|
+
return;
|
|
4689
|
+
}
|
|
4585
4690
|
setCookie(
|
|
4586
4691
|
SHOPIFY_Y,
|
|
4587
|
-
|
|
4692
|
+
trackingValues.uniqueToken || buildUUID(),
|
|
4588
4693
|
longTermLength,
|
|
4589
4694
|
domainWithLeadingDot
|
|
4590
4695
|
);
|
|
4591
4696
|
setCookie(
|
|
4592
4697
|
SHOPIFY_S,
|
|
4593
|
-
|
|
4698
|
+
trackingValues.visitToken || buildUUID(),
|
|
4594
4699
|
shortTermLength,
|
|
4595
4700
|
domainWithLeadingDot
|
|
4596
4701
|
);
|
|
@@ -4598,7 +4703,14 @@ Refer to the authentication https://shopify.dev/api/storefront#authentication do
|
|
|
4598
4703
|
setCookie(SHOPIFY_Y, "", 0, domainWithLeadingDot);
|
|
4599
4704
|
setCookie(SHOPIFY_S, "", 0, domainWithLeadingDot);
|
|
4600
4705
|
}
|
|
4601
|
-
}, [
|
|
4706
|
+
}, [
|
|
4707
|
+
coreCookiesReady,
|
|
4708
|
+
hasUserConsent,
|
|
4709
|
+
domain,
|
|
4710
|
+
checkoutDomain,
|
|
4711
|
+
ignoreDeprecatedCookies
|
|
4712
|
+
]);
|
|
4713
|
+
return coreCookiesReady;
|
|
4602
4714
|
}
|
|
4603
4715
|
function setCookie(name, value, maxage, domain) {
|
|
4604
4716
|
document.cookie = l(name, value, {
|
|
@@ -4608,6 +4720,73 @@ Refer to the authentication https://shopify.dev/api/storefront#authentication do
|
|
|
4608
4720
|
path: "/"
|
|
4609
4721
|
});
|
|
4610
4722
|
}
|
|
4723
|
+
async function fetchTrackingValuesFromBrowser(storefrontAccessToken, storefrontApiDomain = "") {
|
|
4724
|
+
const { uniqueToken, visitToken } = getTrackingValues();
|
|
4725
|
+
const response = await fetch(
|
|
4726
|
+
// TODO: update this endpoint when it becomes stable
|
|
4727
|
+
`${storefrontApiDomain.replace(/\/+$/, "")}/api/unstable/graphql.json`,
|
|
4728
|
+
{
|
|
4729
|
+
method: "POST",
|
|
4730
|
+
headers: {
|
|
4731
|
+
"Content-Type": "application/json",
|
|
4732
|
+
...storefrontAccessToken && {
|
|
4733
|
+
"X-Shopify-Storefront-Access-Token": storefrontAccessToken
|
|
4734
|
+
},
|
|
4735
|
+
...visitToken || uniqueToken ? {
|
|
4736
|
+
[SHOPIFY_VISIT_TOKEN_HEADER]: visitToken,
|
|
4737
|
+
[SHOPIFY_UNIQUE_TOKEN_HEADER]: uniqueToken
|
|
4738
|
+
} : void 0
|
|
4739
|
+
},
|
|
4740
|
+
body: JSON.stringify({
|
|
4741
|
+
query: (
|
|
4742
|
+
// This query ensures we get _cmp (consent) server-timing header, which is not available in other queries.
|
|
4743
|
+
// This value can be passed later to consent-tracking-api and privacy-banner scripts to avoid extra requests.
|
|
4744
|
+
"query ensureCookies { consentManagement { cookies(visitorConsent:{}) { cookieDomain } } }"
|
|
4745
|
+
)
|
|
4746
|
+
})
|
|
4747
|
+
}
|
|
4748
|
+
);
|
|
4749
|
+
if (!response.ok) {
|
|
4750
|
+
throw new Error(
|
|
4751
|
+
`Failed to fetch consent from browser: ${response.status} ${response.statusText}`
|
|
4752
|
+
);
|
|
4753
|
+
}
|
|
4754
|
+
await response.json();
|
|
4755
|
+
getTrackingValues();
|
|
4756
|
+
}
|
|
4757
|
+
function useCoreShopifyCookies({
|
|
4758
|
+
checkoutDomain,
|
|
4759
|
+
storefrontAccessToken,
|
|
4760
|
+
fetchTrackingValues = false
|
|
4761
|
+
}) {
|
|
4762
|
+
const [cookiesReady, setCookiesReady] = React$1.useState(!fetchTrackingValues);
|
|
4763
|
+
const hasFetchedTrackingValues = React$1.useRef(false);
|
|
4764
|
+
React$1.useEffect(() => {
|
|
4765
|
+
if (!fetchTrackingValues) {
|
|
4766
|
+
setCookiesReady(true);
|
|
4767
|
+
return;
|
|
4768
|
+
}
|
|
4769
|
+
if (hasFetchedTrackingValues.current) return;
|
|
4770
|
+
hasFetchedTrackingValues.current = true;
|
|
4771
|
+
fetchTrackingValuesFromBrowser(storefrontAccessToken).catch(
|
|
4772
|
+
(error) => checkoutDomain ? (
|
|
4773
|
+
// Retry with checkout domain if available to at least
|
|
4774
|
+
// get the server-timing values for tracking.
|
|
4775
|
+
fetchTrackingValuesFromBrowser(
|
|
4776
|
+
storefrontAccessToken,
|
|
4777
|
+
checkoutDomain
|
|
4778
|
+
)
|
|
4779
|
+
) : Promise.reject(error)
|
|
4780
|
+
).catch((error) => {
|
|
4781
|
+
console.warn(
|
|
4782
|
+
"[h2:warn:useShopifyCookies] Failed to fetch tracking values from browser: " + (error instanceof Error ? error.message : String(error))
|
|
4783
|
+
);
|
|
4784
|
+
}).finally(() => {
|
|
4785
|
+
setCookiesReady(true);
|
|
4786
|
+
});
|
|
4787
|
+
}, [checkoutDomain, fetchTrackingValues, storefrontAccessToken]);
|
|
4788
|
+
return cookiesReady;
|
|
4789
|
+
}
|
|
4611
4790
|
exports2.AddToCartButton = AddToCartButton;
|
|
4612
4791
|
exports2.AnalyticsEventName = AnalyticsEventName;
|
|
4613
4792
|
exports2.AnalyticsPageType = AnalyticsPageType;
|
|
@@ -4631,6 +4810,8 @@ Refer to the authentication https://shopify.dev/api/storefront#authentication do
|
|
|
4631
4810
|
exports2.SHOPIFY_STOREFRONT_ID_HEADER = SHOPIFY_STOREFRONT_ID_HEADER;
|
|
4632
4811
|
exports2.SHOPIFY_STOREFRONT_S_HEADER = SHOPIFY_STOREFRONT_S_HEADER;
|
|
4633
4812
|
exports2.SHOPIFY_STOREFRONT_Y_HEADER = SHOPIFY_STOREFRONT_Y_HEADER;
|
|
4813
|
+
exports2.SHOPIFY_UNIQUE_TOKEN_HEADER = SHOPIFY_UNIQUE_TOKEN_HEADER;
|
|
4814
|
+
exports2.SHOPIFY_VISIT_TOKEN_HEADER = SHOPIFY_VISIT_TOKEN_HEADER;
|
|
4634
4815
|
exports2.SHOPIFY_Y = SHOPIFY_Y;
|
|
4635
4816
|
exports2.ShopPayButton = ShopPayButton;
|
|
4636
4817
|
exports2.ShopifyProvider = ShopifyProvider;
|
|
@@ -4644,6 +4825,7 @@ Refer to the authentication https://shopify.dev/api/storefront#authentication do
|
|
|
4644
4825
|
exports2.getClientBrowserParameters = getClientBrowserParameters;
|
|
4645
4826
|
exports2.getProductOptions = getProductOptions;
|
|
4646
4827
|
exports2.getShopifyCookies = getShopifyCookies;
|
|
4828
|
+
exports2.getTrackingValues = getTrackingValues;
|
|
4647
4829
|
exports2.isOptionValueCombinationInEncodedVariant = isOptionValueCombinationInEncodedVariant;
|
|
4648
4830
|
exports2.mapSelectedProductOptionToObject = mapSelectedProductOptionToObject;
|
|
4649
4831
|
exports2.parseGid = parseGid;
|