@shopify/hydrogen 2026.4.1 → 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/plugin.js +0 -3
- package/dist/vite/request-events.d.ts +24 -0
- package/package.json +8 -8
|
@@ -613,7 +613,7 @@ function getPrivacyBanner() {
|
|
|
613
613
|
}
|
|
614
614
|
|
|
615
615
|
// package.json
|
|
616
|
-
var version = "2026.4.
|
|
616
|
+
var version = "2026.4.3";
|
|
617
617
|
|
|
618
618
|
// src/analytics-manager/ShopifyAnalytics.tsx
|
|
619
619
|
function getCustomerPrivacyRequired() {
|
|
@@ -2009,7 +2009,7 @@ function generateUUID() {
|
|
|
2009
2009
|
}
|
|
2010
2010
|
|
|
2011
2011
|
// src/version.ts
|
|
2012
|
-
var LIB_VERSION = "2026.4.
|
|
2012
|
+
var LIB_VERSION = "2026.4.3";
|
|
2013
2013
|
|
|
2014
2014
|
// src/utils/graphql.ts
|
|
2015
2015
|
function minifyQuery(string) {
|
|
@@ -2559,7 +2559,7 @@ function cartGetDefault({
|
|
|
2559
2559
|
cartFragment
|
|
2560
2560
|
}) {
|
|
2561
2561
|
return async (cartInput) => {
|
|
2562
|
-
const cartId = getCartId();
|
|
2562
|
+
const cartId = cartInput?.cartId ?? getCartId();
|
|
2563
2563
|
if (!cartId) return null;
|
|
2564
2564
|
const includeVisitorConsent = shouldIncludeVisitorConsent(cartInput);
|
|
2565
2565
|
const [isCustomerLoggedIn, { cart, errors: errors2 }] = await Promise.all([
|
|
@@ -2572,10 +2572,10 @@ function cartGetDefault({
|
|
|
2572
2572
|
}
|
|
2573
2573
|
)
|
|
2574
2574
|
]);
|
|
2575
|
-
if (isCustomerLoggedIn && cart
|
|
2575
|
+
if (isCustomerLoggedIn && cart && typeof cart === "object" && "checkoutUrl" in cart && typeof cart.checkoutUrl === "string") {
|
|
2576
2576
|
const finalCheckoutUrl = new URL(cart.checkoutUrl);
|
|
2577
2577
|
finalCheckoutUrl.searchParams.set("logged_in", "true");
|
|
2578
|
-
cart
|
|
2578
|
+
Object.assign(cart, { checkoutUrl: finalCheckoutUrl.toString() });
|
|
2579
2579
|
}
|
|
2580
2580
|
return cart || errors2 ? formatAPIResult(cart, errors2) : null;
|
|
2581
2581
|
};
|
|
@@ -3528,7 +3528,12 @@ function createCartHandler(options) {
|
|
|
3528
3528
|
...args[0].buyerIdentity
|
|
3529
3529
|
};
|
|
3530
3530
|
const result = await _cartCreate(...args);
|
|
3531
|
-
|
|
3531
|
+
if (result?.cart && (typeof result.cart !== "object" || !("id" in result.cart) || typeof result.cart.id !== "string")) {
|
|
3532
|
+
throw new Error(
|
|
3533
|
+
"[h2:error:createCartHandler] Cart created but response is missing a valid `id` field. Ensure your cart query fragment includes the `id` field."
|
|
3534
|
+
);
|
|
3535
|
+
}
|
|
3536
|
+
cartId = result?.cart && typeof result.cart === "object" && "id" in result.cart && typeof result.cart.id === "string" ? result.cart.id : void 0;
|
|
3532
3537
|
return result;
|
|
3533
3538
|
};
|
|
3534
3539
|
const methods = {
|
|
@@ -3576,7 +3581,10 @@ function createCartHandler(options) {
|
|
|
3576
3581
|
) : await cartCreate({ buyerIdentity: buyerIdentity2 }, optionalParams);
|
|
3577
3582
|
},
|
|
3578
3583
|
updateNote: async (note, optionalParams) => {
|
|
3579
|
-
return cartId || optionalParams?.cartId ? await cartNoteUpdateDefault(mutateOptions)(
|
|
3584
|
+
return cartId || optionalParams?.cartId ? await cartNoteUpdateDefault(mutateOptions)(
|
|
3585
|
+
note,
|
|
3586
|
+
optionalParams
|
|
3587
|
+
) : await cartCreate({ note }, optionalParams);
|
|
3580
3588
|
},
|
|
3581
3589
|
updateSelectedDeliveryOption: cartSelectedDeliveryOptionsUpdateDefault(mutateOptions),
|
|
3582
3590
|
updateAttributes: async (attributes, optionalParams) => {
|
|
@@ -4581,7 +4589,9 @@ function createHydrogenContext(options, additionalContext) {
|
|
|
4581
4589
|
setCartId: cartOptions.setId || cartSetIdDefault(),
|
|
4582
4590
|
cartQueryFragment: cartOptions.queryFragment,
|
|
4583
4591
|
cartMutateFragment: cartOptions.mutateFragment,
|
|
4584
|
-
|
|
4592
|
+
...cartOptions.customMethods && {
|
|
4593
|
+
customMethods: cartOptions.customMethods
|
|
4594
|
+
},
|
|
4585
4595
|
buyerIdentity,
|
|
4586
4596
|
// defaults
|
|
4587
4597
|
storefront,
|
|
@@ -5307,9 +5317,9 @@ function hydrogenPreset() {
|
|
|
5307
5317
|
v8_middleware: true,
|
|
5308
5318
|
v8_splitRouteModules: true,
|
|
5309
5319
|
v8_viteEnvironmentApi: false,
|
|
5310
|
-
unstable_optimizeDeps: true
|
|
5311
|
-
|
|
5312
|
-
|
|
5320
|
+
unstable_optimizeDeps: true
|
|
5321
|
+
},
|
|
5322
|
+
subResourceIntegrity: false
|
|
5313
5323
|
}),
|
|
5314
5324
|
reactRouterConfigResolved: ({ reactRouterConfig }) => {
|
|
5315
5325
|
if (reactRouterConfig.basename && reactRouterConfig.basename !== "/") {
|
|
@@ -5332,9 +5342,9 @@ function hydrogenPreset() {
|
|
|
5332
5342
|
"[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."
|
|
5333
5343
|
);
|
|
5334
5344
|
}
|
|
5335
|
-
if (reactRouterConfig.
|
|
5345
|
+
if (reactRouterConfig.subResourceIntegrity === true) {
|
|
5336
5346
|
throw new Error(
|
|
5337
|
-
"[Hydrogen Preset]
|
|
5347
|
+
"[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."
|
|
5338
5348
|
);
|
|
5339
5349
|
}
|
|
5340
5350
|
}
|
|
@@ -5728,6 +5738,9 @@ var graphiqlLoader = async function graphiqlLoader2({
|
|
|
5728
5738
|
};
|
|
5729
5739
|
|
|
5730
5740
|
// src/routing/redirect.ts
|
|
5741
|
+
var SINGLE_FETCH_DATA_SUFFIX = ".data";
|
|
5742
|
+
var SINGLE_FETCH_ROOT_SEGMENT = "_root.data";
|
|
5743
|
+
var SINGLE_FETCH_TRAILING_SLASH_SEGMENT = "_.data";
|
|
5731
5744
|
async function storefrontRedirect(options) {
|
|
5732
5745
|
const {
|
|
5733
5746
|
storefront,
|
|
@@ -5737,13 +5750,13 @@ async function storefrontRedirect(options) {
|
|
|
5737
5750
|
response = new Response("Not Found", { status: 404 })
|
|
5738
5751
|
} = options;
|
|
5739
5752
|
const url = new URL(request.url);
|
|
5740
|
-
const {
|
|
5741
|
-
const isSoftNavigation =
|
|
5753
|
+
const { searchParams } = url;
|
|
5754
|
+
const { pathname, isSoftNavigation } = parseSingleFetchPathname(url.pathname);
|
|
5742
5755
|
searchParams.delete("redirect");
|
|
5743
5756
|
searchParams.delete("return_to");
|
|
5744
|
-
searchParams.delete("
|
|
5745
|
-
const redirectFrom = (matchQueryParams ? url.
|
|
5746
|
-
if (
|
|
5757
|
+
searchParams.delete("_routes");
|
|
5758
|
+
const redirectFrom = (matchQueryParams ? `${pathname}${url.search}` : pathname).toLowerCase();
|
|
5759
|
+
if (pathname === "/admin" && !noAdminRedirect) {
|
|
5747
5760
|
return createRedirectResponse(
|
|
5748
5761
|
`${storefront.getShopifyDomain()}/admin`,
|
|
5749
5762
|
isSoftNavigation,
|
|
@@ -5793,7 +5806,7 @@ function createRedirectResponse(location, isSoftNavigation, searchParams, matchQ
|
|
|
5793
5806
|
}
|
|
5794
5807
|
if (isSoftNavigation) {
|
|
5795
5808
|
return new Response(null, {
|
|
5796
|
-
status:
|
|
5809
|
+
status: 204,
|
|
5797
5810
|
headers: {
|
|
5798
5811
|
"X-Remix-Redirect": url.toString().replace(TEMP_DOMAIN, ""),
|
|
5799
5812
|
"X-Remix-Status": "301"
|
|
@@ -5806,6 +5819,28 @@ function createRedirectResponse(location, isSoftNavigation, searchParams, matchQ
|
|
|
5806
5819
|
});
|
|
5807
5820
|
}
|
|
5808
5821
|
}
|
|
5822
|
+
function parseSingleFetchPathname(rawPathname) {
|
|
5823
|
+
if (!rawPathname.endsWith(SINGLE_FETCH_DATA_SUFFIX)) {
|
|
5824
|
+
return { pathname: rawPathname, isSoftNavigation: false };
|
|
5825
|
+
}
|
|
5826
|
+
if (rawPathname.endsWith("/" + SINGLE_FETCH_TRAILING_SLASH_SEGMENT)) {
|
|
5827
|
+
return {
|
|
5828
|
+
pathname: rawPathname.slice(
|
|
5829
|
+
0,
|
|
5830
|
+
-SINGLE_FETCH_TRAILING_SLASH_SEGMENT.length
|
|
5831
|
+
),
|
|
5832
|
+
isSoftNavigation: true
|
|
5833
|
+
};
|
|
5834
|
+
}
|
|
5835
|
+
if (rawPathname === "/" + SINGLE_FETCH_ROOT_SEGMENT || rawPathname.endsWith("/" + SINGLE_FETCH_ROOT_SEGMENT)) {
|
|
5836
|
+
const prefix = rawPathname.slice(0, -SINGLE_FETCH_ROOT_SEGMENT.length);
|
|
5837
|
+
return { pathname: prefix || "/", isSoftNavigation: true };
|
|
5838
|
+
}
|
|
5839
|
+
return {
|
|
5840
|
+
pathname: rawPathname.slice(0, -SINGLE_FETCH_DATA_SUFFIX.length),
|
|
5841
|
+
isSoftNavigation: true
|
|
5842
|
+
};
|
|
5843
|
+
}
|
|
5809
5844
|
var REDIRECT_QUERY = `#graphql
|
|
5810
5845
|
query redirects($query: String) {
|
|
5811
5846
|
urlRedirects(first: 1, query: $query) {
|