@shopify/hydrogen 2026.4.2 → 2026.4.3
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 +54 -19
- package/dist/development/index.cjs.map +1 -1
- package/dist/development/index.js +54 -19
- package/dist/development/index.js.map +1 -1
- package/dist/development/react-router-preset.d.ts +3 -3
- package/dist/development/react-router-preset.js +5 -5
- package/dist/development/react-router-preset.js.map +1 -1
- package/dist/oxygen/index.d.ts +24 -0
- package/dist/production/index.cjs +86 -86
- package/dist/production/index.cjs.map +1 -1
- package/dist/production/index.d.cts +89 -173
- package/dist/production/index.d.ts +89 -173
- package/dist/production/index.js +70 -70
- package/dist/production/index.js.map +1 -1
- package/dist/production/react-router-preset.d.ts +3 -3
- package/dist/production/react-router-preset.js +2 -2
- package/dist/react-router.d.ts +12 -2
- package/dist/vite/request-events.d.ts +24 -0
- package/package.json +7 -7
|
@@ -437,7 +437,7 @@ function getPrivacyBanner() {
|
|
|
437
437
|
}
|
|
438
438
|
|
|
439
439
|
// package.json
|
|
440
|
-
var version = "2026.4.
|
|
440
|
+
var version = "2026.4.3";
|
|
441
441
|
|
|
442
442
|
// src/analytics-manager/ShopifyAnalytics.tsx
|
|
443
443
|
function getCustomerPrivacyRequired() {
|
|
@@ -1833,7 +1833,7 @@ function generateUUID() {
|
|
|
1833
1833
|
}
|
|
1834
1834
|
|
|
1835
1835
|
// src/version.ts
|
|
1836
|
-
var LIB_VERSION = "2026.4.
|
|
1836
|
+
var LIB_VERSION = "2026.4.3";
|
|
1837
1837
|
|
|
1838
1838
|
// src/utils/graphql.ts
|
|
1839
1839
|
function minifyQuery(string) {
|
|
@@ -2383,7 +2383,7 @@ function cartGetDefault({
|
|
|
2383
2383
|
cartFragment
|
|
2384
2384
|
}) {
|
|
2385
2385
|
return async (cartInput) => {
|
|
2386
|
-
const cartId = getCartId();
|
|
2386
|
+
const cartId = cartInput?.cartId ?? getCartId();
|
|
2387
2387
|
if (!cartId) return null;
|
|
2388
2388
|
const includeVisitorConsent = shouldIncludeVisitorConsent(cartInput);
|
|
2389
2389
|
const [isCustomerLoggedIn, { cart, errors: errors2 }] = await Promise.all([
|
|
@@ -2396,10 +2396,10 @@ function cartGetDefault({
|
|
|
2396
2396
|
}
|
|
2397
2397
|
)
|
|
2398
2398
|
]);
|
|
2399
|
-
if (isCustomerLoggedIn && cart
|
|
2399
|
+
if (isCustomerLoggedIn && cart && typeof cart === "object" && "checkoutUrl" in cart && typeof cart.checkoutUrl === "string") {
|
|
2400
2400
|
const finalCheckoutUrl = new URL(cart.checkoutUrl);
|
|
2401
2401
|
finalCheckoutUrl.searchParams.set("logged_in", "true");
|
|
2402
|
-
cart
|
|
2402
|
+
Object.assign(cart, { checkoutUrl: finalCheckoutUrl.toString() });
|
|
2403
2403
|
}
|
|
2404
2404
|
return cart || errors2 ? formatAPIResult(cart, errors2) : null;
|
|
2405
2405
|
};
|
|
@@ -3352,7 +3352,12 @@ function createCartHandler(options) {
|
|
|
3352
3352
|
...args[0].buyerIdentity
|
|
3353
3353
|
};
|
|
3354
3354
|
const result = await _cartCreate(...args);
|
|
3355
|
-
|
|
3355
|
+
if (result?.cart && (typeof result.cart !== "object" || !("id" in result.cart) || typeof result.cart.id !== "string")) {
|
|
3356
|
+
throw new Error(
|
|
3357
|
+
"[h2:error:createCartHandler] Cart created but response is missing a valid `id` field. Ensure your cart query fragment includes the `id` field."
|
|
3358
|
+
);
|
|
3359
|
+
}
|
|
3360
|
+
cartId = result?.cart && typeof result.cart === "object" && "id" in result.cart && typeof result.cart.id === "string" ? result.cart.id : void 0;
|
|
3356
3361
|
return result;
|
|
3357
3362
|
};
|
|
3358
3363
|
const methods = {
|
|
@@ -3400,7 +3405,10 @@ function createCartHandler(options) {
|
|
|
3400
3405
|
) : await cartCreate({ buyerIdentity: buyerIdentity2 }, optionalParams);
|
|
3401
3406
|
},
|
|
3402
3407
|
updateNote: async (note, optionalParams) => {
|
|
3403
|
-
return cartId || optionalParams?.cartId ? await cartNoteUpdateDefault(mutateOptions)(
|
|
3408
|
+
return cartId || optionalParams?.cartId ? await cartNoteUpdateDefault(mutateOptions)(
|
|
3409
|
+
note,
|
|
3410
|
+
optionalParams
|
|
3411
|
+
) : await cartCreate({ note }, optionalParams);
|
|
3404
3412
|
},
|
|
3405
3413
|
updateSelectedDeliveryOption: cartSelectedDeliveryOptionsUpdateDefault(mutateOptions),
|
|
3406
3414
|
updateAttributes: async (attributes, optionalParams) => {
|
|
@@ -4405,7 +4413,9 @@ function createHydrogenContext(options, additionalContext) {
|
|
|
4405
4413
|
setCartId: cartOptions.setId || cartSetIdDefault(),
|
|
4406
4414
|
cartQueryFragment: cartOptions.queryFragment,
|
|
4407
4415
|
cartMutateFragment: cartOptions.mutateFragment,
|
|
4408
|
-
|
|
4416
|
+
...cartOptions.customMethods && {
|
|
4417
|
+
customMethods: cartOptions.customMethods
|
|
4418
|
+
},
|
|
4409
4419
|
buyerIdentity,
|
|
4410
4420
|
// defaults
|
|
4411
4421
|
storefront,
|
|
@@ -5131,9 +5141,9 @@ function hydrogenPreset() {
|
|
|
5131
5141
|
v8_middleware: true,
|
|
5132
5142
|
v8_splitRouteModules: true,
|
|
5133
5143
|
v8_viteEnvironmentApi: false,
|
|
5134
|
-
unstable_optimizeDeps: true
|
|
5135
|
-
|
|
5136
|
-
|
|
5144
|
+
unstable_optimizeDeps: true
|
|
5145
|
+
},
|
|
5146
|
+
subResourceIntegrity: false
|
|
5137
5147
|
}),
|
|
5138
5148
|
reactRouterConfigResolved: ({ reactRouterConfig }) => {
|
|
5139
5149
|
if (reactRouterConfig.basename && reactRouterConfig.basename !== "/") {
|
|
@@ -5156,9 +5166,9 @@ function hydrogenPreset() {
|
|
|
5156
5166
|
"[Hydrogen Preset] buildEnd is not supported in Hydrogen 2025.7.0.\nReason: Hydrogen CLI bypasses React Router buildEnd hook execution.\nWorkaround: Use external build scripts or package.json post-build hooks."
|
|
5157
5167
|
);
|
|
5158
5168
|
}
|
|
5159
|
-
if (reactRouterConfig.
|
|
5169
|
+
if (reactRouterConfig.subResourceIntegrity === true) {
|
|
5160
5170
|
throw new Error(
|
|
5161
|
-
"[Hydrogen Preset]
|
|
5171
|
+
"[Hydrogen Preset] subResourceIntegrity cannot be enabled.\nReason: Conflicts with Hydrogen CSP nonce-based authentication.\nImpact: Would break Content Security Policy and cause script execution failures."
|
|
5162
5172
|
);
|
|
5163
5173
|
}
|
|
5164
5174
|
}
|
|
@@ -5552,6 +5562,9 @@ var graphiqlLoader = async function graphiqlLoader2({
|
|
|
5552
5562
|
};
|
|
5553
5563
|
|
|
5554
5564
|
// src/routing/redirect.ts
|
|
5565
|
+
var SINGLE_FETCH_DATA_SUFFIX = ".data";
|
|
5566
|
+
var SINGLE_FETCH_ROOT_SEGMENT = "_root.data";
|
|
5567
|
+
var SINGLE_FETCH_TRAILING_SLASH_SEGMENT = "_.data";
|
|
5555
5568
|
async function storefrontRedirect(options) {
|
|
5556
5569
|
const {
|
|
5557
5570
|
storefront,
|
|
@@ -5561,13 +5574,13 @@ async function storefrontRedirect(options) {
|
|
|
5561
5574
|
response = new Response("Not Found", { status: 404 })
|
|
5562
5575
|
} = options;
|
|
5563
5576
|
const url = new URL(request.url);
|
|
5564
|
-
const {
|
|
5565
|
-
const isSoftNavigation =
|
|
5577
|
+
const { searchParams } = url;
|
|
5578
|
+
const { pathname, isSoftNavigation } = parseSingleFetchPathname(url.pathname);
|
|
5566
5579
|
searchParams.delete("redirect");
|
|
5567
5580
|
searchParams.delete("return_to");
|
|
5568
|
-
searchParams.delete("
|
|
5569
|
-
const redirectFrom = (matchQueryParams ? url.
|
|
5570
|
-
if (
|
|
5581
|
+
searchParams.delete("_routes");
|
|
5582
|
+
const redirectFrom = (matchQueryParams ? `${pathname}${url.search}` : pathname).toLowerCase();
|
|
5583
|
+
if (pathname === "/admin" && !noAdminRedirect) {
|
|
5571
5584
|
return createRedirectResponse(
|
|
5572
5585
|
`${storefront.getShopifyDomain()}/admin`,
|
|
5573
5586
|
isSoftNavigation,
|
|
@@ -5617,7 +5630,7 @@ function createRedirectResponse(location, isSoftNavigation, searchParams, matchQ
|
|
|
5617
5630
|
}
|
|
5618
5631
|
if (isSoftNavigation) {
|
|
5619
5632
|
return new Response(null, {
|
|
5620
|
-
status:
|
|
5633
|
+
status: 204,
|
|
5621
5634
|
headers: {
|
|
5622
5635
|
"X-Remix-Redirect": url.toString().replace(TEMP_DOMAIN, ""),
|
|
5623
5636
|
"X-Remix-Status": "301"
|
|
@@ -5630,6 +5643,28 @@ function createRedirectResponse(location, isSoftNavigation, searchParams, matchQ
|
|
|
5630
5643
|
});
|
|
5631
5644
|
}
|
|
5632
5645
|
}
|
|
5646
|
+
function parseSingleFetchPathname(rawPathname) {
|
|
5647
|
+
if (!rawPathname.endsWith(SINGLE_FETCH_DATA_SUFFIX)) {
|
|
5648
|
+
return { pathname: rawPathname, isSoftNavigation: false };
|
|
5649
|
+
}
|
|
5650
|
+
if (rawPathname.endsWith("/" + SINGLE_FETCH_TRAILING_SLASH_SEGMENT)) {
|
|
5651
|
+
return {
|
|
5652
|
+
pathname: rawPathname.slice(
|
|
5653
|
+
0,
|
|
5654
|
+
-SINGLE_FETCH_TRAILING_SLASH_SEGMENT.length
|
|
5655
|
+
),
|
|
5656
|
+
isSoftNavigation: true
|
|
5657
|
+
};
|
|
5658
|
+
}
|
|
5659
|
+
if (rawPathname === "/" + SINGLE_FETCH_ROOT_SEGMENT || rawPathname.endsWith("/" + SINGLE_FETCH_ROOT_SEGMENT)) {
|
|
5660
|
+
const prefix = rawPathname.slice(0, -SINGLE_FETCH_ROOT_SEGMENT.length);
|
|
5661
|
+
return { pathname: prefix || "/", isSoftNavigation: true };
|
|
5662
|
+
}
|
|
5663
|
+
return {
|
|
5664
|
+
pathname: rawPathname.slice(0, -SINGLE_FETCH_DATA_SUFFIX.length),
|
|
5665
|
+
isSoftNavigation: true
|
|
5666
|
+
};
|
|
5667
|
+
}
|
|
5633
5668
|
var REDIRECT_QUERY = `#graphql
|
|
5634
5669
|
query redirects($query: String) {
|
|
5635
5670
|
urlRedirects(first: 1, query: $query) {
|