@shopify/hydrogen 2024.7.3 → 2024.7.5
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/development/index.cjs +562 -87
- package/dist/development/index.cjs.map +1 -1
- package/dist/development/index.js +560 -88
- package/dist/development/index.js.map +1 -1
- package/dist/production/index.cjs +224 -82
- package/dist/production/index.cjs.map +1 -1
- package/dist/production/index.d.cts +100 -11
- package/dist/production/index.d.ts +100 -11
- package/dist/production/index.js +173 -34
- package/dist/production/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -511,7 +511,7 @@ var errorOnce = (string) => {
|
|
|
511
511
|
};
|
|
512
512
|
|
|
513
513
|
// src/version.ts
|
|
514
|
-
var LIB_VERSION = "2024.7.
|
|
514
|
+
var LIB_VERSION = "2024.7.5";
|
|
515
515
|
|
|
516
516
|
// src/utils/graphql.ts
|
|
517
517
|
function minifyQuery(string) {
|
|
@@ -2968,6 +2968,7 @@ CartForm.ACTIONS = {
|
|
|
2968
2968
|
BuyerIdentityUpdate: "BuyerIdentityUpdate",
|
|
2969
2969
|
Create: "Create",
|
|
2970
2970
|
DiscountCodesUpdate: "DiscountCodesUpdate",
|
|
2971
|
+
GiftCardCodesUpdate: "GiftCardCodesUpdate",
|
|
2971
2972
|
LinesAdd: "LinesAdd",
|
|
2972
2973
|
LinesRemove: "LinesRemove",
|
|
2973
2974
|
LinesUpdate: "LinesUpdate",
|
|
@@ -3007,6 +3008,7 @@ var MINIMAL_CART_FRAGMENT = `#graphql
|
|
|
3007
3008
|
fragment CartApiMutation on Cart {
|
|
3008
3009
|
id
|
|
3009
3010
|
totalQuantity
|
|
3011
|
+
checkoutUrl
|
|
3010
3012
|
}
|
|
3011
3013
|
`;
|
|
3012
3014
|
|
|
@@ -3358,6 +3360,42 @@ var CART_DISCOUNT_CODE_UPDATE_MUTATION = (cartFragment = MINIMAL_CART_FRAGMENT)
|
|
|
3358
3360
|
${USER_ERROR_FRAGMENT}
|
|
3359
3361
|
`;
|
|
3360
3362
|
|
|
3363
|
+
// src/cart/queries/cartGiftCardCodeUpdateDefault.ts
|
|
3364
|
+
function cartGiftCardCodesUpdateDefault(options) {
|
|
3365
|
+
return async (giftCardCodes, optionalParams) => {
|
|
3366
|
+
const uniqueCodes = giftCardCodes.filter((value, index, array) => {
|
|
3367
|
+
return array.indexOf(value) === index;
|
|
3368
|
+
});
|
|
3369
|
+
const { cartGiftCardCodesUpdate, errors: errors2 } = await options.storefront.mutate(CART_GIFT_CARD_CODE_UPDATE_MUTATION(options.cartFragment), {
|
|
3370
|
+
variables: {
|
|
3371
|
+
cartId: options.getCartId(),
|
|
3372
|
+
giftCardCodes: uniqueCodes,
|
|
3373
|
+
...optionalParams
|
|
3374
|
+
}
|
|
3375
|
+
});
|
|
3376
|
+
return formatAPIResult(cartGiftCardCodesUpdate, errors2);
|
|
3377
|
+
};
|
|
3378
|
+
}
|
|
3379
|
+
var CART_GIFT_CARD_CODE_UPDATE_MUTATION = (cartFragment = MINIMAL_CART_FRAGMENT) => `#graphql
|
|
3380
|
+
mutation cartGiftCardCodesUpdate(
|
|
3381
|
+
$cartId: ID!
|
|
3382
|
+
$giftCardCodes: [String!]!
|
|
3383
|
+
$language: LanguageCode
|
|
3384
|
+
$country: CountryCode
|
|
3385
|
+
) @inContext(country: $country, language: $language) {
|
|
3386
|
+
cartGiftCardCodesUpdate(cartId: $cartId, giftCardCodes: $giftCardCodes) {
|
|
3387
|
+
cart {
|
|
3388
|
+
...CartApiMutation
|
|
3389
|
+
}
|
|
3390
|
+
userErrors {
|
|
3391
|
+
...CartApiError
|
|
3392
|
+
}
|
|
3393
|
+
}
|
|
3394
|
+
}
|
|
3395
|
+
${cartFragment}
|
|
3396
|
+
${USER_ERROR_FRAGMENT}
|
|
3397
|
+
`;
|
|
3398
|
+
|
|
3361
3399
|
// src/cart/queries/cartBuyerIdentityUpdateDefault.ts
|
|
3362
3400
|
function cartBuyerIdentityUpdateDefault(options) {
|
|
3363
3401
|
return async (buyerIdentity, optionalParams) => {
|
|
@@ -3646,6 +3684,12 @@ function createCartHandler(options) {
|
|
|
3646
3684
|
optionalParams
|
|
3647
3685
|
) : await cartCreate({ discountCodes }, optionalParams);
|
|
3648
3686
|
},
|
|
3687
|
+
updateGiftCardCodes: async (giftCardCodes, optionalParams) => {
|
|
3688
|
+
return cartId || optionalParams?.cartId ? await cartGiftCardCodesUpdateDefault(mutateOptions)(
|
|
3689
|
+
giftCardCodes,
|
|
3690
|
+
optionalParams
|
|
3691
|
+
) : await cartCreate({ giftCardCodes }, optionalParams);
|
|
3692
|
+
},
|
|
3649
3693
|
updateBuyerIdentity: async (buyerIdentity, optionalParams) => {
|
|
3650
3694
|
return cartId || optionalParams?.cartId ? await cartBuyerIdentityUpdateDefault(mutateOptions)(
|
|
3651
3695
|
buyerIdentity,
|
|
@@ -3758,6 +3802,10 @@ function useOptimisticCart(cart) {
|
|
|
3758
3802
|
if (isOptimistic) {
|
|
3759
3803
|
optimisticCart.isOptimistic = isOptimistic;
|
|
3760
3804
|
}
|
|
3805
|
+
optimisticCart.totalQuantity = cartLines.reduce(
|
|
3806
|
+
(sum, line) => sum + line.quantity,
|
|
3807
|
+
0
|
|
3808
|
+
);
|
|
3761
3809
|
return optimisticCart;
|
|
3762
3810
|
}
|
|
3763
3811
|
function VariantSelector({
|
|
@@ -3972,10 +4020,16 @@ function createCSPHeader(nonce, props) {
|
|
|
3972
4020
|
);
|
|
3973
4021
|
}
|
|
3974
4022
|
}
|
|
3975
|
-
if (combinedDirectives.scriptSrc instanceof Array
|
|
3976
|
-
combinedDirectives.scriptSrc
|
|
3977
|
-
|
|
3978
|
-
|
|
4023
|
+
if (combinedDirectives.scriptSrc instanceof Array) {
|
|
4024
|
+
combinedDirectives.scriptSrc = [
|
|
4025
|
+
...combinedDirectives.scriptSrc.filter((ss) => !ss.startsWith(`'nonce`)),
|
|
4026
|
+
nonceString
|
|
4027
|
+
];
|
|
4028
|
+
} else if (combinedDirectives.defaultSrc instanceof Array) {
|
|
4029
|
+
combinedDirectives.defaultSrc = [
|
|
4030
|
+
...combinedDirectives.defaultSrc.filter((ss) => !ss.startsWith(`'nonce`)),
|
|
4031
|
+
nonceString
|
|
4032
|
+
];
|
|
3979
4033
|
}
|
|
3980
4034
|
return cspBuilder__default.default({
|
|
3981
4035
|
directives: combinedDirectives
|
|
@@ -3994,7 +4048,6 @@ function addCspDirective(currentValue, value) {
|
|
|
3994
4048
|
var Script = react.forwardRef(
|
|
3995
4049
|
(props, ref) => {
|
|
3996
4050
|
const { waitForHydration, src, ...rest } = props;
|
|
3997
|
-
if (!src) throw new Error("Script components require a `src` prop");
|
|
3998
4051
|
if (waitForHydration) return /* @__PURE__ */ jsxRuntime.jsx(LazyScript, { src, options: rest });
|
|
3999
4052
|
const nonce = useNonce();
|
|
4000
4053
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -4013,6 +4066,10 @@ function LazyScript({
|
|
|
4013
4066
|
src,
|
|
4014
4067
|
options
|
|
4015
4068
|
}) {
|
|
4069
|
+
if (!src)
|
|
4070
|
+
throw new Error(
|
|
4071
|
+
"`waitForHydration` with the Script component requires a `src` prop"
|
|
4072
|
+
);
|
|
4016
4073
|
hydrogenReact.useLoadScript(src, {
|
|
4017
4074
|
attributes: options
|
|
4018
4075
|
});
|
|
@@ -4131,15 +4188,33 @@ function useCustomerPrivacy(props) {
|
|
|
4131
4188
|
onReady,
|
|
4132
4189
|
...consentConfig
|
|
4133
4190
|
} = props;
|
|
4134
|
-
|
|
4135
|
-
|
|
4136
|
-
|
|
4137
|
-
{
|
|
4138
|
-
attributes: {
|
|
4139
|
-
id: "customer-privacy-api"
|
|
4140
|
-
}
|
|
4191
|
+
hydrogenReact.useLoadScript(withPrivacyBanner ? CONSENT_API_WITH_BANNER : CONSENT_API, {
|
|
4192
|
+
attributes: {
|
|
4193
|
+
id: "customer-privacy-api"
|
|
4141
4194
|
}
|
|
4142
|
-
);
|
|
4195
|
+
});
|
|
4196
|
+
const { observing, setLoaded } = useApisLoaded({
|
|
4197
|
+
withPrivacyBanner,
|
|
4198
|
+
onLoaded: onReady
|
|
4199
|
+
});
|
|
4200
|
+
const config = react.useMemo(() => {
|
|
4201
|
+
const { checkoutDomain, storefrontAccessToken } = consentConfig;
|
|
4202
|
+
if (!checkoutDomain) logMissingConfig("checkoutDomain");
|
|
4203
|
+
if (!storefrontAccessToken) logMissingConfig("storefrontAccessToken");
|
|
4204
|
+
if (storefrontAccessToken.startsWith("shpat_") || storefrontAccessToken.length !== 32) {
|
|
4205
|
+
console.error(
|
|
4206
|
+
`[h2:error:useCustomerPrivacy] It looks like you passed a private access token, make sure to use the public token`
|
|
4207
|
+
);
|
|
4208
|
+
}
|
|
4209
|
+
const config2 = {
|
|
4210
|
+
checkoutRootDomain: checkoutDomain,
|
|
4211
|
+
storefrontAccessToken,
|
|
4212
|
+
storefrontRootDomain: parseStoreDomain(checkoutDomain),
|
|
4213
|
+
country: consentConfig.country,
|
|
4214
|
+
locale: consentConfig.locale
|
|
4215
|
+
};
|
|
4216
|
+
return config2;
|
|
4217
|
+
}, [consentConfig, parseStoreDomain, logMissingConfig]);
|
|
4143
4218
|
react.useEffect(() => {
|
|
4144
4219
|
const consentCollectedHandler = (event) => {
|
|
4145
4220
|
if (onVisitorConsentCollected) {
|
|
@@ -4158,54 +4233,166 @@ function useCustomerPrivacy(props) {
|
|
|
4158
4233
|
};
|
|
4159
4234
|
}, [onVisitorConsentCollected]);
|
|
4160
4235
|
react.useEffect(() => {
|
|
4161
|
-
if (
|
|
4162
|
-
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
|
|
4167
|
-
|
|
4168
|
-
|
|
4169
|
-
)
|
|
4170
|
-
|
|
4171
|
-
|
|
4172
|
-
|
|
4173
|
-
|
|
4236
|
+
if (!withPrivacyBanner || observing.current.privacyBanner) return;
|
|
4237
|
+
observing.current.privacyBanner = true;
|
|
4238
|
+
let customPrivacyBanner = void 0;
|
|
4239
|
+
const privacyBannerWatcher = {
|
|
4240
|
+
configurable: true,
|
|
4241
|
+
get() {
|
|
4242
|
+
return customPrivacyBanner;
|
|
4243
|
+
},
|
|
4244
|
+
set(value) {
|
|
4245
|
+
if (typeof value === "object" && value !== null && "showPreferences" in value && "loadBanner" in value) {
|
|
4246
|
+
const privacyBanner = value;
|
|
4247
|
+
privacyBanner.loadBanner(config);
|
|
4248
|
+
customPrivacyBanner = overridePrivacyBannerMethods({
|
|
4249
|
+
privacyBanner,
|
|
4250
|
+
config
|
|
4251
|
+
});
|
|
4252
|
+
setLoaded.privacyBanner();
|
|
4253
|
+
}
|
|
4254
|
+
}
|
|
4174
4255
|
};
|
|
4175
|
-
|
|
4176
|
-
|
|
4177
|
-
|
|
4178
|
-
|
|
4179
|
-
|
|
4180
|
-
|
|
4181
|
-
|
|
4182
|
-
|
|
4256
|
+
Object.defineProperty(window, "privacyBanner", privacyBannerWatcher);
|
|
4257
|
+
}, [
|
|
4258
|
+
withPrivacyBanner,
|
|
4259
|
+
config,
|
|
4260
|
+
overridePrivacyBannerMethods,
|
|
4261
|
+
setLoaded.privacyBanner
|
|
4262
|
+
]);
|
|
4263
|
+
react.useEffect(() => {
|
|
4264
|
+
if (observing.current.customerPrivacy) return;
|
|
4265
|
+
observing.current.customerPrivacy = true;
|
|
4266
|
+
let customCustomerPrivacy = null;
|
|
4267
|
+
let customShopify = void 0;
|
|
4268
|
+
Object.defineProperty(window, "Shopify", {
|
|
4269
|
+
configurable: true,
|
|
4270
|
+
get() {
|
|
4271
|
+
return customShopify;
|
|
4272
|
+
},
|
|
4273
|
+
set(value) {
|
|
4274
|
+
if (typeof value === "object" && value !== null && Object.keys(value).length === 0) {
|
|
4275
|
+
customShopify = value;
|
|
4276
|
+
Object.defineProperty(window.Shopify, "customerPrivacy", {
|
|
4277
|
+
configurable: true,
|
|
4278
|
+
get() {
|
|
4279
|
+
return customCustomerPrivacy;
|
|
4280
|
+
},
|
|
4281
|
+
set(value2) {
|
|
4282
|
+
if (typeof value2 === "object" && value2 !== null && "setTrackingConsent" in value2) {
|
|
4283
|
+
const customerPrivacy = value2;
|
|
4284
|
+
customCustomerPrivacy = {
|
|
4285
|
+
...customerPrivacy,
|
|
4286
|
+
setTrackingConsent: overrideCustomerPrivacySetTrackingConsent(
|
|
4287
|
+
{ customerPrivacy, config }
|
|
4288
|
+
)
|
|
4289
|
+
};
|
|
4290
|
+
customShopify = {
|
|
4291
|
+
...customShopify,
|
|
4292
|
+
customerPrivacy: customCustomerPrivacy
|
|
4293
|
+
};
|
|
4294
|
+
setLoaded.customerPrivacy();
|
|
4295
|
+
}
|
|
4296
|
+
}
|
|
4297
|
+
});
|
|
4183
4298
|
}
|
|
4184
|
-
});
|
|
4185
|
-
storefrontRootDomain = sameDomainParts.reverse().join(".");
|
|
4186
|
-
if (storefrontRootDomain) {
|
|
4187
|
-
config.storefrontRootDomain = storefrontRootDomain;
|
|
4188
4299
|
}
|
|
4300
|
+
});
|
|
4301
|
+
}, [
|
|
4302
|
+
config,
|
|
4303
|
+
overrideCustomerPrivacySetTrackingConsent,
|
|
4304
|
+
setLoaded.customerPrivacy
|
|
4305
|
+
]);
|
|
4306
|
+
const result = {
|
|
4307
|
+
customerPrivacy: getCustomerPrivacy()
|
|
4308
|
+
};
|
|
4309
|
+
if (withPrivacyBanner) {
|
|
4310
|
+
result.privacyBanner = getPrivacyBanner();
|
|
4311
|
+
}
|
|
4312
|
+
return result;
|
|
4313
|
+
}
|
|
4314
|
+
function useApisLoaded({
|
|
4315
|
+
withPrivacyBanner,
|
|
4316
|
+
onLoaded
|
|
4317
|
+
}) {
|
|
4318
|
+
const observing = react.useRef({ customerPrivacy: false, privacyBanner: false });
|
|
4319
|
+
const [apisLoaded, setApisLoaded] = react.useState(
|
|
4320
|
+
withPrivacyBanner ? [false, false] : [false]
|
|
4321
|
+
);
|
|
4322
|
+
const loaded = apisLoaded.every(Boolean);
|
|
4323
|
+
const setLoaded = {
|
|
4324
|
+
customerPrivacy: () => {
|
|
4325
|
+
if (withPrivacyBanner) {
|
|
4326
|
+
setApisLoaded((prev) => [true, prev[1]]);
|
|
4327
|
+
} else {
|
|
4328
|
+
setApisLoaded(() => [true]);
|
|
4329
|
+
}
|
|
4330
|
+
},
|
|
4331
|
+
privacyBanner: () => {
|
|
4332
|
+
if (!withPrivacyBanner) {
|
|
4333
|
+
return;
|
|
4334
|
+
}
|
|
4335
|
+
setApisLoaded((prev) => [prev[0], true]);
|
|
4189
4336
|
}
|
|
4190
|
-
|
|
4191
|
-
|
|
4337
|
+
};
|
|
4338
|
+
react.useEffect(() => {
|
|
4339
|
+
if (loaded && onLoaded) {
|
|
4340
|
+
onLoaded();
|
|
4192
4341
|
}
|
|
4193
|
-
|
|
4194
|
-
|
|
4195
|
-
|
|
4196
|
-
|
|
4197
|
-
|
|
4198
|
-
|
|
4199
|
-
|
|
4200
|
-
|
|
4201
|
-
|
|
4202
|
-
|
|
4203
|
-
|
|
4342
|
+
}, [loaded, onLoaded]);
|
|
4343
|
+
return { observing, setLoaded };
|
|
4344
|
+
}
|
|
4345
|
+
function parseStoreDomain(checkoutDomain) {
|
|
4346
|
+
if (typeof window === "undefined") return;
|
|
4347
|
+
const host = window.document.location.host;
|
|
4348
|
+
const checkoutDomainParts = checkoutDomain.split(".").reverse();
|
|
4349
|
+
const currentDomainParts = host.split(".").reverse();
|
|
4350
|
+
const sameDomainParts = [];
|
|
4351
|
+
checkoutDomainParts.forEach((part, index) => {
|
|
4352
|
+
if (part === currentDomainParts[index]) {
|
|
4353
|
+
sameDomainParts.push(part);
|
|
4204
4354
|
}
|
|
4205
|
-
|
|
4206
|
-
|
|
4207
|
-
|
|
4208
|
-
|
|
4355
|
+
});
|
|
4356
|
+
return sameDomainParts.reverse().join(".");
|
|
4357
|
+
}
|
|
4358
|
+
function overrideCustomerPrivacySetTrackingConsent({
|
|
4359
|
+
customerPrivacy,
|
|
4360
|
+
config
|
|
4361
|
+
}) {
|
|
4362
|
+
const original = customerPrivacy.setTrackingConsent;
|
|
4363
|
+
function updatedSetTrackingConsent(consent, callback) {
|
|
4364
|
+
original(
|
|
4365
|
+
{
|
|
4366
|
+
...consent,
|
|
4367
|
+
headlessStorefront: true,
|
|
4368
|
+
...config
|
|
4369
|
+
},
|
|
4370
|
+
callback
|
|
4371
|
+
);
|
|
4372
|
+
}
|
|
4373
|
+
return updatedSetTrackingConsent;
|
|
4374
|
+
}
|
|
4375
|
+
function overridePrivacyBannerMethods({
|
|
4376
|
+
privacyBanner,
|
|
4377
|
+
config
|
|
4378
|
+
}) {
|
|
4379
|
+
const originalLoadBanner = privacyBanner.loadBanner;
|
|
4380
|
+
const originalShowPreferences = privacyBanner.showPreferences;
|
|
4381
|
+
function loadBanner(userConfig) {
|
|
4382
|
+
if (typeof userConfig === "object") {
|
|
4383
|
+
originalLoadBanner({ ...config, ...userConfig });
|
|
4384
|
+
return;
|
|
4385
|
+
}
|
|
4386
|
+
originalLoadBanner(config);
|
|
4387
|
+
}
|
|
4388
|
+
function showPreferences(userConfig) {
|
|
4389
|
+
if (typeof userConfig === "object") {
|
|
4390
|
+
originalShowPreferences({ ...config, ...userConfig });
|
|
4391
|
+
return;
|
|
4392
|
+
}
|
|
4393
|
+
originalShowPreferences(config);
|
|
4394
|
+
}
|
|
4395
|
+
return { loadBanner, showPreferences };
|
|
4209
4396
|
}
|
|
4210
4397
|
function getCustomerPrivacy() {
|
|
4211
4398
|
try {
|
|
@@ -4214,6 +4401,13 @@ function getCustomerPrivacy() {
|
|
|
4214
4401
|
return null;
|
|
4215
4402
|
}
|
|
4216
4403
|
}
|
|
4404
|
+
function getPrivacyBanner() {
|
|
4405
|
+
try {
|
|
4406
|
+
return window && window?.privacyBanner ? window.privacyBanner : null;
|
|
4407
|
+
} catch (e) {
|
|
4408
|
+
return null;
|
|
4409
|
+
}
|
|
4410
|
+
}
|
|
4217
4411
|
function getCustomerPrivacyRequired() {
|
|
4218
4412
|
const customerPrivacy = getCustomerPrivacy();
|
|
4219
4413
|
if (!customerPrivacy) {
|
|
@@ -4232,30 +4426,19 @@ function ShopifyAnalytics({
|
|
|
4232
4426
|
const [shopifyReady, setShopifyReady] = react.useState(false);
|
|
4233
4427
|
const [privacyReady, setPrivacyReady] = react.useState(false);
|
|
4234
4428
|
const init = react.useRef(false);
|
|
4429
|
+
const { checkoutDomain, storefrontAccessToken, language } = consent;
|
|
4235
4430
|
const { ready: shopifyAnalyticsReady } = register2("Internal_Shopify_Analytics");
|
|
4236
|
-
const { ready: customerPrivacyReady } = register2(
|
|
4237
|
-
"Internal_Shopify_CustomerPrivacy"
|
|
4238
|
-
);
|
|
4239
|
-
const analyticsReady = () => {
|
|
4240
|
-
shopifyReady && privacyReady && onReady();
|
|
4241
|
-
};
|
|
4242
|
-
const setCustomerPrivacyReady = () => {
|
|
4243
|
-
setPrivacyReady(true);
|
|
4244
|
-
customerPrivacyReady();
|
|
4245
|
-
analyticsReady();
|
|
4246
|
-
};
|
|
4247
|
-
const { checkoutDomain, storefrontAccessToken, withPrivacyBanner } = consent;
|
|
4248
4431
|
useCustomerPrivacy({
|
|
4432
|
+
...consent,
|
|
4433
|
+
locale: language,
|
|
4249
4434
|
checkoutDomain: !checkoutDomain ? "mock.shop" : checkoutDomain,
|
|
4250
4435
|
storefrontAccessToken: !storefrontAccessToken ? "abcdefghijklmnopqrstuvwxyz123456" : storefrontAccessToken,
|
|
4251
|
-
|
|
4252
|
-
|
|
4253
|
-
onReady: () => {
|
|
4254
|
-
setTimeout(setCustomerPrivacyReady, 3e3);
|
|
4255
|
-
}
|
|
4436
|
+
onVisitorConsentCollected: () => setPrivacyReady(true),
|
|
4437
|
+
onReady: () => setPrivacyReady(true)
|
|
4256
4438
|
});
|
|
4257
4439
|
hydrogenReact.useShopifyCookies({
|
|
4258
|
-
hasUserConsent:
|
|
4440
|
+
hasUserConsent: privacyReady ? canTrack() : true,
|
|
4441
|
+
// must be initialized with true
|
|
4259
4442
|
domain,
|
|
4260
4443
|
checkoutDomain
|
|
4261
4444
|
});
|
|
@@ -4267,10 +4450,14 @@ function ShopifyAnalytics({
|
|
|
4267
4450
|
subscribe2(AnalyticsEvent.COLLECTION_VIEWED, collectionViewHandler);
|
|
4268
4451
|
subscribe2(AnalyticsEvent.SEARCH_VIEWED, searchViewHandler);
|
|
4269
4452
|
subscribe2(AnalyticsEvent.PRODUCT_ADD_TO_CART, productAddedToCartHandler);
|
|
4270
|
-
shopifyAnalyticsReady();
|
|
4271
4453
|
setShopifyReady(true);
|
|
4272
|
-
|
|
4273
|
-
|
|
4454
|
+
}, [subscribe2]);
|
|
4455
|
+
react.useEffect(() => {
|
|
4456
|
+
if (shopifyReady && privacyReady) {
|
|
4457
|
+
shopifyAnalyticsReady();
|
|
4458
|
+
onReady();
|
|
4459
|
+
}
|
|
4460
|
+
}, [shopifyReady, privacyReady, onReady]);
|
|
4274
4461
|
return null;
|
|
4275
4462
|
}
|
|
4276
4463
|
function logMissingConfig2(fieldName) {
|
|
@@ -4591,12 +4778,12 @@ function CartAnalytics({
|
|
|
4591
4778
|
}, [cart, prevCart, publish2, shop, customData, canTrack]);
|
|
4592
4779
|
return null;
|
|
4593
4780
|
}
|
|
4594
|
-
var
|
|
4781
|
+
var PERF_KIT_URL = "https://cdn.shopify.com/shopifycloud/perf-kit/shopify-perf-kit-1.0.0.min.js";
|
|
4595
4782
|
function PerfKit({ shop }) {
|
|
4596
4783
|
const loadedEvent = react.useRef(false);
|
|
4597
4784
|
const { subscribe: subscribe2, register: register2 } = useAnalytics();
|
|
4598
4785
|
const { ready } = register2("Internal_Shopify_Perf_Kit");
|
|
4599
|
-
const scriptStatus = hydrogenReact.useLoadScript(
|
|
4786
|
+
const scriptStatus = hydrogenReact.useLoadScript(PERF_KIT_URL, {
|
|
4600
4787
|
attributes: {
|
|
4601
4788
|
id: "perfkit",
|
|
4602
4789
|
"data-application": "hydrogen",
|
|
@@ -4640,7 +4827,9 @@ var defaultAnalyticsContext = {
|
|
|
4640
4827
|
subscribe: () => {
|
|
4641
4828
|
},
|
|
4642
4829
|
register: () => ({ ready: () => {
|
|
4643
|
-
} })
|
|
4830
|
+
} }),
|
|
4831
|
+
customerPrivacy: null,
|
|
4832
|
+
privacyBanner: null
|
|
4644
4833
|
};
|
|
4645
4834
|
var AnalyticsContext = react.createContext(
|
|
4646
4835
|
defaultAnalyticsContext
|
|
@@ -4719,7 +4908,7 @@ function AnalyticsProvider({
|
|
|
4719
4908
|
}) {
|
|
4720
4909
|
const listenerSet = react.useRef(false);
|
|
4721
4910
|
const { shop } = useShopAnalytics(shopProp);
|
|
4722
|
-
const [
|
|
4911
|
+
const [analyticsLoaded, setAnalyticsLoaded] = react.useState(
|
|
4723
4912
|
customCanTrack ? true : false
|
|
4724
4913
|
);
|
|
4725
4914
|
const [carts, setCarts] = react.useState({ cart: null, prevCart: null });
|
|
@@ -4746,6 +4935,15 @@ function AnalyticsProvider({
|
|
|
4746
4935
|
);
|
|
4747
4936
|
errorOnce(errorMsg);
|
|
4748
4937
|
}
|
|
4938
|
+
if (!consent?.country) {
|
|
4939
|
+
consent.country = "US";
|
|
4940
|
+
}
|
|
4941
|
+
if (!consent?.language) {
|
|
4942
|
+
consent.language = "EN";
|
|
4943
|
+
}
|
|
4944
|
+
if (consent.withPrivacyBanner === void 0) {
|
|
4945
|
+
consent.withPrivacyBanner = true;
|
|
4946
|
+
}
|
|
4749
4947
|
}
|
|
4750
4948
|
}
|
|
4751
4949
|
const value = react.useMemo(() => {
|
|
@@ -4757,13 +4955,13 @@ function AnalyticsProvider({
|
|
|
4757
4955
|
},
|
|
4758
4956
|
shop,
|
|
4759
4957
|
subscribe,
|
|
4760
|
-
register
|
|
4958
|
+
register,
|
|
4959
|
+
customerPrivacy: getCustomerPrivacy(),
|
|
4960
|
+
privacyBanner: getPrivacyBanner()
|
|
4761
4961
|
};
|
|
4762
4962
|
}, [
|
|
4763
|
-
|
|
4764
|
-
canTrack(),
|
|
4963
|
+
analyticsLoaded,
|
|
4765
4964
|
canTrack,
|
|
4766
|
-
JSON.stringify(canTrack),
|
|
4767
4965
|
carts,
|
|
4768
4966
|
carts.cart?.updatedAt,
|
|
4769
4967
|
carts.prevCart,
|
|
@@ -4772,7 +4970,9 @@ function AnalyticsProvider({
|
|
|
4772
4970
|
customData,
|
|
4773
4971
|
shop,
|
|
4774
4972
|
register,
|
|
4775
|
-
JSON.stringify(registers)
|
|
4973
|
+
JSON.stringify(registers),
|
|
4974
|
+
getCustomerPrivacy,
|
|
4975
|
+
getPrivacyBanner
|
|
4776
4976
|
]);
|
|
4777
4977
|
return /* @__PURE__ */ jsxRuntime.jsxs(AnalyticsContext.Provider, { value, children: [
|
|
4778
4978
|
children,
|
|
@@ -4784,7 +4984,7 @@ function AnalyticsProvider({
|
|
|
4784
4984
|
consent,
|
|
4785
4985
|
onReady: () => {
|
|
4786
4986
|
listenerSet.current = true;
|
|
4787
|
-
|
|
4987
|
+
setAnalyticsLoaded(true);
|
|
4788
4988
|
setCanTrack(() => shopifyCanTrack);
|
|
4789
4989
|
},
|
|
4790
4990
|
domain: cookieDomain
|
|
@@ -4953,12 +5153,284 @@ function getStorefrontHeaders(request) {
|
|
|
4953
5153
|
purpose: getHeader(request, "purpose")
|
|
4954
5154
|
};
|
|
4955
5155
|
}
|
|
5156
|
+
|
|
5157
|
+
// src/sitemap/sitemap.ts
|
|
5158
|
+
var SITEMAP_INDEX_PREFIX = `<?xml version="1.0" encoding="UTF-8"?>
|
|
5159
|
+
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
5160
|
+
`;
|
|
5161
|
+
var SITEMAP_INDEX_SUFFIX = `
|
|
5162
|
+
</sitemapindex>`;
|
|
5163
|
+
var SITEMAP_PREFIX = `<?xml version="1.0" encoding="UTF-8"?>
|
|
5164
|
+
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml">`;
|
|
5165
|
+
var SITEMAP_SUFFIX = `</urlset>`;
|
|
5166
|
+
async function getSitemapIndex(options) {
|
|
5167
|
+
const {
|
|
5168
|
+
storefront,
|
|
5169
|
+
request,
|
|
5170
|
+
types = [
|
|
5171
|
+
"products",
|
|
5172
|
+
"pages",
|
|
5173
|
+
"collections",
|
|
5174
|
+
"metaObjects",
|
|
5175
|
+
"articles",
|
|
5176
|
+
"blogs"
|
|
5177
|
+
],
|
|
5178
|
+
customChildSitemaps = []
|
|
5179
|
+
} = options;
|
|
5180
|
+
if (!request || !request.url)
|
|
5181
|
+
throw new Error("A request object is required to generate a sitemap index");
|
|
5182
|
+
if (!storefront || !storefront.query)
|
|
5183
|
+
throw new Error(
|
|
5184
|
+
"A storefront client is required to generate a sitemap index"
|
|
5185
|
+
);
|
|
5186
|
+
const data = await storefront.query(SITEMAP_INDEX_QUERY, {
|
|
5187
|
+
storefrontApiVersion: "unstable"
|
|
5188
|
+
});
|
|
5189
|
+
if (!data) {
|
|
5190
|
+
throw new Response("No data found", { status: 404 });
|
|
5191
|
+
}
|
|
5192
|
+
const baseUrl = new URL(request.url).origin;
|
|
5193
|
+
const body = SITEMAP_INDEX_PREFIX + types.map((type) => {
|
|
5194
|
+
if (!data[type]) {
|
|
5195
|
+
throw new Error(
|
|
5196
|
+
`[h2:sitemap:error] No data found for type ${type}. Check types passed to \`getSitemapIndex\``
|
|
5197
|
+
);
|
|
5198
|
+
}
|
|
5199
|
+
return getSiteMapLinks(type, data[type].pagesCount.count, baseUrl);
|
|
5200
|
+
}).join("\n") + customChildSitemaps.map(
|
|
5201
|
+
(url) => " <sitemap><loc>" + (baseUrl + (url.startsWith("/") ? url : "/" + url)) + "</loc></sitemap>"
|
|
5202
|
+
).join("\n") + SITEMAP_INDEX_SUFFIX;
|
|
5203
|
+
return new Response(body, {
|
|
5204
|
+
headers: {
|
|
5205
|
+
"Content-Type": "application/xml",
|
|
5206
|
+
"Cache-Control": `max-age=${60 * 60 * 24}`
|
|
5207
|
+
}
|
|
5208
|
+
});
|
|
5209
|
+
}
|
|
5210
|
+
async function getSitemap(options) {
|
|
5211
|
+
const {
|
|
5212
|
+
storefront,
|
|
5213
|
+
request,
|
|
5214
|
+
params,
|
|
5215
|
+
getLink,
|
|
5216
|
+
locales = [],
|
|
5217
|
+
getChangeFreq,
|
|
5218
|
+
noItemsFallback = "/"
|
|
5219
|
+
} = options;
|
|
5220
|
+
if (!params)
|
|
5221
|
+
throw new Error(
|
|
5222
|
+
"[h2:sitemap:error] Remix params object is required to generate a sitemap"
|
|
5223
|
+
);
|
|
5224
|
+
if (!request || !request.url)
|
|
5225
|
+
throw new Error("A request object is required to generate a sitemap");
|
|
5226
|
+
if (!storefront || !storefront.query)
|
|
5227
|
+
throw new Error("A storefront client is required to generate a index");
|
|
5228
|
+
if (!getLink)
|
|
5229
|
+
throw new Error(
|
|
5230
|
+
"A `getLink` function to generate each resource is required to build a sitemap"
|
|
5231
|
+
);
|
|
5232
|
+
if (!params.type || !params.page)
|
|
5233
|
+
throw new Response("No data found", { status: 404 });
|
|
5234
|
+
const type = params.type;
|
|
5235
|
+
const query = QUERIES[type];
|
|
5236
|
+
if (!query) throw new Response("Not found", { status: 404 });
|
|
5237
|
+
const data = await storefront.query(query, {
|
|
5238
|
+
variables: {
|
|
5239
|
+
page: parseInt(params.page, 10)
|
|
5240
|
+
},
|
|
5241
|
+
storefrontApiVersion: "unstable"
|
|
5242
|
+
});
|
|
5243
|
+
const baseUrl = new URL(request.url).origin;
|
|
5244
|
+
let body = "";
|
|
5245
|
+
if (!data?.sitemap?.resources?.items?.length) {
|
|
5246
|
+
body = SITEMAP_PREFIX + `
|
|
5247
|
+
<url><loc>${baseUrl + noItemsFallback}</loc></url>
|
|
5248
|
+
` + SITEMAP_SUFFIX;
|
|
5249
|
+
} else {
|
|
5250
|
+
body = SITEMAP_PREFIX + data.sitemap.resources.items.map((item) => {
|
|
5251
|
+
return renderUrlTag({
|
|
5252
|
+
getChangeFreq,
|
|
5253
|
+
url: getLink({
|
|
5254
|
+
type: item.type ?? type,
|
|
5255
|
+
baseUrl,
|
|
5256
|
+
handle: item.handle
|
|
5257
|
+
}),
|
|
5258
|
+
type,
|
|
5259
|
+
getLink,
|
|
5260
|
+
updatedAt: item.updatedAt,
|
|
5261
|
+
handle: item.handle,
|
|
5262
|
+
metaobjectType: item.type,
|
|
5263
|
+
locales,
|
|
5264
|
+
baseUrl
|
|
5265
|
+
});
|
|
5266
|
+
}).join("\n") + SITEMAP_SUFFIX;
|
|
5267
|
+
}
|
|
5268
|
+
return new Response(body, {
|
|
5269
|
+
headers: {
|
|
5270
|
+
"Content-Type": "application/xml",
|
|
5271
|
+
"Cache-Control": `max-age=${60 * 60 * 24}`
|
|
5272
|
+
}
|
|
5273
|
+
});
|
|
5274
|
+
}
|
|
5275
|
+
function getSiteMapLinks(resource, count, baseUrl) {
|
|
5276
|
+
let links = ``;
|
|
5277
|
+
for (let i = 1; i <= count; i++) {
|
|
5278
|
+
links += ` <sitemap><loc>${baseUrl}/sitemap/${resource}/${i}.xml</loc></sitemap>
|
|
5279
|
+
`;
|
|
5280
|
+
}
|
|
5281
|
+
return links;
|
|
5282
|
+
}
|
|
5283
|
+
function renderUrlTag({
|
|
5284
|
+
url,
|
|
5285
|
+
updatedAt,
|
|
5286
|
+
locales,
|
|
5287
|
+
type,
|
|
5288
|
+
getLink,
|
|
5289
|
+
baseUrl,
|
|
5290
|
+
handle,
|
|
5291
|
+
getChangeFreq,
|
|
5292
|
+
metaobjectType
|
|
5293
|
+
}) {
|
|
5294
|
+
return `<url>
|
|
5295
|
+
<loc>${url}</loc>
|
|
5296
|
+
<lastmod>${updatedAt}</lastmod>
|
|
5297
|
+
<changefreq>${getChangeFreq ? getChangeFreq({ type: metaobjectType ?? type, handle }) : "weekly"}</changefreq>
|
|
5298
|
+
${locales.map(
|
|
5299
|
+
(locale) => renderAlternateTag(
|
|
5300
|
+
getLink({ type: metaobjectType ?? type, baseUrl, handle, locale }),
|
|
5301
|
+
locale
|
|
5302
|
+
)
|
|
5303
|
+
).join("\n")}
|
|
5304
|
+
</url>
|
|
5305
|
+
`.trim();
|
|
5306
|
+
}
|
|
5307
|
+
function renderAlternateTag(url, locale) {
|
|
5308
|
+
return ` <xhtml:link rel="alternate" hreflang="${locale}" href="${url}" />`;
|
|
5309
|
+
}
|
|
5310
|
+
var PRODUCT_SITEMAP_QUERY = `#graphql
|
|
5311
|
+
query SitemapProducts($page: Int!) {
|
|
5312
|
+
sitemap(type: PRODUCT) {
|
|
5313
|
+
resources(page: $page) {
|
|
5314
|
+
items {
|
|
5315
|
+
handle
|
|
5316
|
+
updatedAt
|
|
5317
|
+
}
|
|
5318
|
+
}
|
|
5319
|
+
}
|
|
5320
|
+
}
|
|
5321
|
+
`;
|
|
5322
|
+
var COLLECTION_SITEMAP_QUERY = `#graphql
|
|
5323
|
+
query SitemapCollections($page: Int!) {
|
|
5324
|
+
sitemap(type: COLLECTION) {
|
|
5325
|
+
resources(page: $page) {
|
|
5326
|
+
items {
|
|
5327
|
+
handle
|
|
5328
|
+
updatedAt
|
|
5329
|
+
}
|
|
5330
|
+
}
|
|
5331
|
+
}
|
|
5332
|
+
}
|
|
5333
|
+
`;
|
|
5334
|
+
var ARTICLE_SITEMAP_QUERY = `#graphql
|
|
5335
|
+
query SitemapArticles($page: Int!) {
|
|
5336
|
+
sitemap(type: ARTICLE) {
|
|
5337
|
+
resources(page: $page) {
|
|
5338
|
+
items {
|
|
5339
|
+
handle
|
|
5340
|
+
updatedAt
|
|
5341
|
+
}
|
|
5342
|
+
}
|
|
5343
|
+
}
|
|
5344
|
+
}
|
|
5345
|
+
`;
|
|
5346
|
+
var PAGE_SITEMAP_QUERY = `#graphql
|
|
5347
|
+
query SitemapPages($page: Int!) {
|
|
5348
|
+
sitemap(type: PAGE) {
|
|
5349
|
+
resources(page: $page) {
|
|
5350
|
+
items {
|
|
5351
|
+
handle
|
|
5352
|
+
updatedAt
|
|
5353
|
+
}
|
|
5354
|
+
}
|
|
5355
|
+
}
|
|
5356
|
+
}
|
|
5357
|
+
`;
|
|
5358
|
+
var BLOG_SITEMAP_QUERY = `#graphql
|
|
5359
|
+
query SitemapBlogs($page: Int!) {
|
|
5360
|
+
sitemap(type: BLOG) {
|
|
5361
|
+
resources(page: $page) {
|
|
5362
|
+
items {
|
|
5363
|
+
handle
|
|
5364
|
+
updatedAt
|
|
5365
|
+
}
|
|
5366
|
+
}
|
|
5367
|
+
}
|
|
5368
|
+
}
|
|
5369
|
+
`;
|
|
5370
|
+
var METAOBJECT_SITEMAP_QUERY = `#graphql
|
|
5371
|
+
query SitemapMetaobjects($page: Int!) {
|
|
5372
|
+
sitemap(type: METAOBJECT_PAGE) {
|
|
5373
|
+
resources(page: $page) {
|
|
5374
|
+
items {
|
|
5375
|
+
handle
|
|
5376
|
+
updatedAt
|
|
5377
|
+
... on SitemapResourceMetaobject {
|
|
5378
|
+
type
|
|
5379
|
+
}
|
|
5380
|
+
}
|
|
5381
|
+
}
|
|
5382
|
+
}
|
|
5383
|
+
}
|
|
5384
|
+
`;
|
|
5385
|
+
var SITEMAP_INDEX_QUERY = `#graphql
|
|
5386
|
+
query SitemapIndex {
|
|
5387
|
+
products: sitemap(type: PRODUCT) {
|
|
5388
|
+
pagesCount {
|
|
5389
|
+
count
|
|
5390
|
+
}
|
|
5391
|
+
}
|
|
5392
|
+
collections: sitemap(type: COLLECTION) {
|
|
5393
|
+
pagesCount {
|
|
5394
|
+
count
|
|
5395
|
+
}
|
|
5396
|
+
}
|
|
5397
|
+
articles: sitemap(type: ARTICLE) {
|
|
5398
|
+
pagesCount {
|
|
5399
|
+
count
|
|
5400
|
+
}
|
|
5401
|
+
}
|
|
5402
|
+
pages: sitemap(type: PAGE) {
|
|
5403
|
+
pagesCount {
|
|
5404
|
+
count
|
|
5405
|
+
}
|
|
5406
|
+
}
|
|
5407
|
+
blogs: sitemap(type: BLOG) {
|
|
5408
|
+
pagesCount {
|
|
5409
|
+
count
|
|
5410
|
+
}
|
|
5411
|
+
}
|
|
5412
|
+
metaObjects: sitemap(type: METAOBJECT_PAGE) {
|
|
5413
|
+
pagesCount {
|
|
5414
|
+
count
|
|
5415
|
+
}
|
|
5416
|
+
}
|
|
5417
|
+
}
|
|
5418
|
+
`;
|
|
5419
|
+
var QUERIES = {
|
|
5420
|
+
products: PRODUCT_SITEMAP_QUERY,
|
|
5421
|
+
articles: ARTICLE_SITEMAP_QUERY,
|
|
5422
|
+
collections: COLLECTION_SITEMAP_QUERY,
|
|
5423
|
+
pages: PAGE_SITEMAP_QUERY,
|
|
5424
|
+
blogs: BLOG_SITEMAP_QUERY,
|
|
5425
|
+
metaObjects: METAOBJECT_SITEMAP_QUERY
|
|
5426
|
+
};
|
|
4956
5427
|
//! @see: https://shopify.dev/docs/api/storefront/latest/mutations/cartCreate
|
|
4957
5428
|
//! @see https://shopify.dev/docs/api/storefront/latest/queries/cart
|
|
4958
5429
|
//! @see: https://shopify.dev/docs/api/storefront/latest/mutations/cartLinesAdd
|
|
4959
5430
|
//! @see: https://shopify.dev/docs/api/storefront/latest/mutations/cartLinesUpdate
|
|
4960
5431
|
//! @see: https://shopify.dev/docs/api/storefront/latest/mutations/cartLinesRemove
|
|
4961
5432
|
//! @see https://shopify.dev/docs/api/storefront/latest/mutations/cartDiscountCodesUpdate
|
|
5433
|
+
//! @see https://shopify.dev/docs/api/storefront/latest/mutations/cartGiftCardCodesUpdate
|
|
4962
5434
|
//! @see https://shopify.dev/docs/api/storefront/latest/mutations/cartBuyerIdentityUpdate
|
|
4963
5435
|
//! @see https://shopify.dev/docs/api/storefront/latest/mutations/cartNoteUpdate
|
|
4964
5436
|
//! @see https://shopify.dev/docs/api/storefront/latest/mutations/cartSelectedDeliveryOptionsUpdate
|
|
@@ -5070,6 +5542,7 @@ exports.cartCreateDefault = cartCreateDefault;
|
|
|
5070
5542
|
exports.cartDiscountCodesUpdateDefault = cartDiscountCodesUpdateDefault;
|
|
5071
5543
|
exports.cartGetDefault = cartGetDefault;
|
|
5072
5544
|
exports.cartGetIdDefault = cartGetIdDefault;
|
|
5545
|
+
exports.cartGiftCardCodesUpdateDefault = cartGiftCardCodesUpdateDefault;
|
|
5073
5546
|
exports.cartLinesAddDefault = cartLinesAddDefault;
|
|
5074
5547
|
exports.cartLinesRemoveDefault = cartLinesRemoveDefault;
|
|
5075
5548
|
exports.cartLinesUpdateDefault = cartLinesUpdateDefault;
|
|
@@ -5094,6 +5567,8 @@ exports.getSeoMeta = getSeoMeta;
|
|
|
5094
5567
|
exports.getShopAnalytics = getShopAnalytics;
|
|
5095
5568
|
exports.graphiqlLoader = graphiqlLoader;
|
|
5096
5569
|
exports.storefrontRedirect = storefrontRedirect;
|
|
5570
|
+
exports.unstable__getSitemap = getSitemap;
|
|
5571
|
+
exports.unstable__getSitemapIndex = getSitemapIndex;
|
|
5097
5572
|
exports.useAnalytics = useAnalytics;
|
|
5098
5573
|
exports.useCustomerPrivacy = useCustomerPrivacy;
|
|
5099
5574
|
exports.useNonce = useNonce;
|