@shopify/create-hydrogen 5.0.23 → 5.0.25
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/assets/hydrogen/bundle/analyzer.html +155 -148
- package/dist/assets/hydrogen/starter/.cursor/rules/hydrogen-react-router.mdc +5 -3
- package/dist/assets/hydrogen/starter/CHANGELOG.md +97 -9
- package/dist/assets/hydrogen/starter/app/components/AddToCartButton.tsx +1 -1
- package/dist/assets/hydrogen/starter/app/components/CartLineItem.tsx +1 -1
- package/dist/assets/hydrogen/starter/app/components/CartMain.tsx +1 -1
- package/dist/assets/hydrogen/starter/app/components/CartSummary.tsx +62 -29
- package/dist/assets/hydrogen/starter/app/components/Header.tsx +1 -1
- package/dist/assets/hydrogen/starter/app/components/PageLayout.tsx +1 -1
- package/dist/assets/hydrogen/starter/app/components/ProductForm.tsx +2 -2
- package/dist/assets/hydrogen/starter/app/components/SearchForm.tsx +1 -1
- package/dist/assets/hydrogen/starter/app/components/SearchFormPredictive.tsx +8 -3
- package/dist/assets/hydrogen/starter/app/components/SearchResults.tsx +3 -11
- package/dist/assets/hydrogen/starter/app/components/SearchResultsPredictive.tsx +2 -6
- package/dist/assets/hydrogen/starter/app/entry.client.tsx +10 -2
- package/dist/assets/hydrogen/starter/app/entry.server.tsx +5 -3
- package/dist/assets/hydrogen/starter/app/graphql/customer-account/CustomerAddressMutations.ts +7 -4
- package/dist/assets/hydrogen/starter/app/graphql/customer-account/CustomerDetailsQuery.ts +1 -1
- package/dist/assets/hydrogen/starter/app/graphql/customer-account/CustomerOrderQuery.ts +4 -1
- package/dist/assets/hydrogen/starter/app/graphql/customer-account/CustomerOrdersQuery.ts +10 -5
- package/dist/assets/hydrogen/starter/app/graphql/customer-account/CustomerUpdateMutation.ts +3 -2
- package/dist/assets/hydrogen/starter/app/lib/context.ts +34 -17
- package/dist/assets/hydrogen/starter/app/lib/fragments.ts +1 -0
- package/dist/assets/hydrogen/starter/app/lib/orderFilters.ts +90 -0
- package/dist/assets/hydrogen/starter/app/lib/redirect.ts +1 -1
- package/dist/assets/hydrogen/starter/app/lib/session.ts +1 -1
- package/dist/assets/hydrogen/starter/app/lib/variants.ts +1 -1
- package/dist/assets/hydrogen/starter/app/root.tsx +23 -18
- package/dist/assets/hydrogen/starter/app/routes/$.tsx +2 -2
- package/dist/assets/hydrogen/starter/app/routes/[robots.txt].tsx +2 -2
- package/dist/assets/hydrogen/starter/app/routes/[sitemap.xml].tsx +2 -3
- package/dist/assets/hydrogen/starter/app/routes/_index.tsx +12 -8
- package/dist/assets/hydrogen/starter/app/routes/account.$.tsx +4 -3
- package/dist/assets/hydrogen/starter/app/routes/account._index.tsx +1 -1
- package/dist/assets/hydrogen/starter/app/routes/account.addresses.tsx +15 -11
- package/dist/assets/hydrogen/starter/app/routes/account.orders.$id.tsx +47 -22
- package/dist/assets/hydrogen/starter/app/routes/account.orders._index.tsx +152 -23
- package/dist/assets/hydrogen/starter/app/routes/account.profile.tsx +11 -8
- package/dist/assets/hydrogen/starter/app/routes/account.tsx +16 -4
- package/dist/assets/hydrogen/starter/app/routes/account_.authorize.tsx +2 -2
- package/dist/assets/hydrogen/starter/app/routes/account_.login.tsx +5 -3
- package/dist/assets/hydrogen/starter/app/routes/account_.logout.tsx +3 -2
- package/dist/assets/hydrogen/starter/app/routes/api.$version.[graphql.json].tsx +2 -2
- package/dist/assets/hydrogen/starter/app/routes/blogs.$blogHandle.$articleHandle.tsx +6 -10
- package/dist/assets/hydrogen/starter/app/routes/blogs.$blogHandle._index.tsx +10 -7
- package/dist/assets/hydrogen/starter/app/routes/blogs._index.tsx +13 -7
- package/dist/assets/hydrogen/starter/app/routes/cart.$lines.tsx +3 -2
- package/dist/assets/hydrogen/starter/app/routes/cart.tsx +13 -9
- package/dist/assets/hydrogen/starter/app/routes/collections.$handle.tsx +8 -11
- package/dist/assets/hydrogen/starter/app/routes/collections._index.tsx +6 -6
- package/dist/assets/hydrogen/starter/app/routes/collections.all.tsx +10 -7
- package/dist/assets/hydrogen/starter/app/routes/discount.$code.tsx +3 -2
- package/dist/assets/hydrogen/starter/app/routes/pages.$handle.tsx +8 -6
- package/dist/assets/hydrogen/starter/app/routes/policies.$handle.tsx +7 -4
- package/dist/assets/hydrogen/starter/app/routes/policies._index.tsx +19 -13
- package/dist/assets/hydrogen/starter/app/routes/products.$handle.tsx +9 -6
- package/dist/assets/hydrogen/starter/app/routes/search.tsx +14 -14
- package/dist/assets/hydrogen/starter/app/routes/sitemap.$type.$page[.xml].tsx +2 -3
- package/dist/assets/hydrogen/starter/app/routes.ts +1 -1
- package/dist/assets/hydrogen/starter/app/styles/app.css +53 -1
- package/dist/assets/hydrogen/starter/customer-accountapi.generated.d.ts +47 -13
- package/dist/assets/hydrogen/starter/env.d.ts +1 -39
- package/dist/assets/hydrogen/starter/eslint.config.js +35 -52
- package/dist/assets/hydrogen/starter/package.json +14 -15
- package/dist/assets/hydrogen/starter/react-router.config.ts +9 -3
- package/dist/assets/hydrogen/starter/server.ts +7 -7
- package/dist/assets/hydrogen/starter/storefrontapi.generated.d.ts +1 -1
- package/dist/assets/hydrogen/starter/tsconfig.json +17 -13
- package/dist/assets/hydrogen/starter/vite.config.ts +4 -1
- package/dist/assets/hydrogen/virtual-routes/components/RequestDetails.jsx +13 -20
- package/dist/assets/hydrogen/virtual-routes/routes/[.]well-known.appspecific.com[.]chrome[.]devtools[.]json.jsx +37 -0
- package/dist/chunk-2LZQLWDR.js +1189 -0
- package/dist/{chunk-EO6F7WJJ.js → chunk-6YUUFKYO.js} +1 -1
- package/dist/chunk-AUULK6IN.js +5 -0
- package/dist/chunk-CJKPLQJ7.js +51 -0
- package/dist/{chunk-MNT4XW23.js → chunk-LBUW5UHX.js} +1 -1
- package/dist/chunk-RUCJI22O.js +3 -0
- package/dist/{chunk-PMDMUCNY.js → chunk-VXJIQGAB.js} +1 -1
- package/dist/chunk-Y5VZE2FH.js +32 -0
- package/dist/chunk-ZLNTSIDN.js +2 -0
- package/dist/create-app.js +293 -288
- package/dist/{del-72VO4HYK.js → del-VDYQZFAQ.js} +1 -1
- package/dist/devtools-3BYEW2L2.js +8 -0
- package/dist/error-handler-XRI3ZDLO.js +2 -0
- package/dist/is-wsl-52AELLDM.js +2 -0
- package/dist/{morph-3JSBLNUD.js → morph-S2LU6PQ4.js} +7 -7
- package/dist/{multipart-parser-QIHQVIZA.js → multipart-parser-MX4R5XJM.js} +1 -1
- package/dist/open-PMJ32HTM.js +2 -0
- package/dist/out-U7AI7XUQ.js +2 -0
- package/package.json +4 -2
- package/dist/chokidar-FXMI63T6.js +0 -12
- package/dist/chunk-3LZ6M5C2.js +0 -3
- package/dist/chunk-D7CI46F7.js +0 -10
- package/dist/chunk-FB327AH7.js +0 -5
- package/dist/chunk-MZPD7BFF.js +0 -23
- package/dist/chunk-NIHY2BIB.js +0 -1180
- package/dist/chunk-UASQ33JG.js +0 -45
- package/dist/chunk-VMIOG46Y.js +0 -2
- package/dist/devtools-DGRGSZU7.js +0 -8
- package/dist/error-handler-O653XSNU.js +0 -2
- package/dist/is-wsl-LL6KGQIK.js +0 -2
- package/dist/open-OD6DRFEG.js +0 -2
- package/dist/out-DXB3K325.js +0 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
description:
|
|
3
|
-
globs:
|
|
4
|
-
alwaysApply:
|
|
2
|
+
description:
|
|
3
|
+
globs:
|
|
4
|
+
alwaysApply: true
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# React Router Import Rule for Hydrogen
|
|
@@ -29,6 +29,8 @@ When you see imports from Remix packages, replace them with their equivalent Rea
|
|
|
29
29
|
| `@remix-run/server-runtime` | `react-router` |
|
|
30
30
|
| `@remix-run/testing` | `react-router` |
|
|
31
31
|
|
|
32
|
+
NEVER USE 'react-router-dom' imports!
|
|
33
|
+
|
|
32
34
|
## Common Import Examples
|
|
33
35
|
|
|
34
36
|
```js
|
|
@@ -1,5 +1,102 @@
|
|
|
1
1
|
# skeleton
|
|
2
2
|
|
|
3
|
+
## 2025.7.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- Update Storefront API and Customer Account API to version 2025-07 ([#3082](https://github.com/Shopify/hydrogen/pull/3082)) by [@juanpprieto](https://github.com/juanpprieto)
|
|
8
|
+
|
|
9
|
+
This update includes:
|
|
10
|
+
- Updated API version constants to 2025-07
|
|
11
|
+
- Regenerated GraphQL types for both Storefront and Customer Account APIs
|
|
12
|
+
- Updated all hardcoded API version references in documentation and tests
|
|
13
|
+
- Regenerated skeleton template types
|
|
14
|
+
- Updated skeleton's @shopify/cli dependency to ~3.83.3
|
|
15
|
+
|
|
16
|
+
Breaking changes may occur due to API schema changes between versions.
|
|
17
|
+
|
|
18
|
+
### Patch Changes
|
|
19
|
+
|
|
20
|
+
- Fix defer/streaming in development & preview ([#3039](https://github.com/Shopify/hydrogen/pull/3039)) by [@kdaviduik](https://github.com/kdaviduik)
|
|
21
|
+
|
|
22
|
+
- Upgrade Miniflare from v2 to v4 in mini-oxygen package. ([#3039](https://github.com/Shopify/hydrogen/pull/3039)) by [@kdaviduik](https://github.com/kdaviduik)
|
|
23
|
+
- Internal MiniOxygen API has been refactored to work with Miniflare v4's new architecture.
|
|
24
|
+
- Simplified MiniOxygen class - no longer extends MiniflareCore.
|
|
25
|
+
- Updated global fetch handling to use Miniflare v4's `outboundService` API.
|
|
26
|
+
- Fixed test infrastructure to use project-relative temporary directories.
|
|
27
|
+
- Added support for Oxygen compatibility parameters (`compatibilityDate`, `compatibilityFlags`).
|
|
28
|
+
- Removed dependency on multiple `@miniflare/*` packages in favor of the consolidated `miniflare` package.
|
|
29
|
+
|
|
30
|
+
- Update and pin react-router to 7.9.2 for 2025.7.0 ([#3138](https://github.com/Shopify/hydrogen/pull/3138)) by [@juanpprieto](https://github.com/juanpprieto)
|
|
31
|
+
|
|
32
|
+
- Add TypeScript ESLint rules for promise handling to prevent Cloudflare Workers errors ([#3146](https://github.com/Shopify/hydrogen/pull/3146)) by [@kdaviduik](https://github.com/kdaviduik)
|
|
33
|
+
|
|
34
|
+
Added `@typescript-eslint/no-floating-promises` and `@typescript-eslint/no-misused-promises` rules to help prevent "The script will never generate a response" errors when deploying to Oxygen/Cloudflare Workers. These rules ensure promises are properly handled with await, return, or void operators, as recommended by [Cloudflare's error documentation](https://developers.cloudflare.com/workers/observability/errors/#the-script-will-never-generate-a-response-errors).
|
|
35
|
+
|
|
36
|
+
- Fixed React Context error that occurred during client-side hydration when using Content Security Policy (CSP) with nonces. The error "Cannot read properties of null (reading 'useContext')" was caused by the `NonceProvider` being present during server-side rendering but missing during client hydration. ([#3082](https://github.com/Shopify/hydrogen/pull/3082)) by [@juanpprieto](https://github.com/juanpprieto)
|
|
37
|
+
|
|
38
|
+
#### Changes for Existing Projects
|
|
39
|
+
|
|
40
|
+
If you have customized your `app/entry.client.tsx` file, you may need to wrap your app with the `NonceProvider` during hydration to avoid this error:
|
|
41
|
+
|
|
42
|
+
```diff
|
|
43
|
+
// app/entry.client.tsx
|
|
44
|
+
import {HydratedRouter} from 'react-router/dom';
|
|
45
|
+
import {startTransition, StrictMode} from 'react';
|
|
46
|
+
import {hydrateRoot} from 'react-dom/client';
|
|
47
|
+
+ import {NonceProvider} from '@shopify/hydrogen';
|
|
48
|
+
|
|
49
|
+
if (!window.location.origin.includes('webcache.googleusercontent.com')) {
|
|
50
|
+
startTransition(() => {
|
|
51
|
+
+ // Extract nonce from existing script tags
|
|
52
|
+
+ const existingNonce = document
|
|
53
|
+
+ .querySelector<HTMLScriptElement>('script[nonce]')
|
|
54
|
+
+ ?.nonce;
|
|
55
|
+
+
|
|
56
|
+
hydrateRoot(
|
|
57
|
+
document,
|
|
58
|
+
<StrictMode>
|
|
59
|
+
- <HydratedRouter />
|
|
60
|
+
+ <NonceProvider value={existingNonce}>
|
|
61
|
+
+ <HydratedRouter />
|
|
62
|
+
+ </NonceProvider>
|
|
63
|
+
</StrictMode>,
|
|
64
|
+
);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
This ensures the React Context tree matches between server and client rendering, preventing hydration mismatches.
|
|
70
|
+
|
|
71
|
+
#### Package Changes
|
|
72
|
+
- **@shopify/hydrogen**: Exported `NonceProvider` from the main package to allow client-side usage and simplified Vite configuration to improve React Context stability during development
|
|
73
|
+
- **skeleton**: Updated the template's `entry.client.tsx` to include the `NonceProvider` wrapper during hydration
|
|
74
|
+
|
|
75
|
+
- Add `fulfillmentStatus` to CAAPI order query and route ([#3039](https://github.com/Shopify/hydrogen/pull/3039)) by [@kdaviduik](https://github.com/kdaviduik)
|
|
76
|
+
|
|
77
|
+
- Add GraphQL @defer directive support to storefront client ([#3039](https://github.com/Shopify/hydrogen/pull/3039)) by [@kdaviduik](https://github.com/kdaviduik)
|
|
78
|
+
|
|
79
|
+
- Unpin react-router and react-router-dom versions in the skeleton template ([#3039](https://github.com/Shopify/hydrogen/pull/3039)) by [@kdaviduik](https://github.com/kdaviduik)
|
|
80
|
+
|
|
81
|
+
- Add `@inContext` language support to Customer Account API mutations ([#3039](https://github.com/Shopify/hydrogen/pull/3039)) by [@kdaviduik](https://github.com/kdaviduik)
|
|
82
|
+
|
|
83
|
+
- Add order filtering support to the skeleton /account/orders route for Customer Account API flow ([#3125](https://github.com/Shopify/hydrogen/pull/3125)) by [@juanpprieto](https://github.com/juanpprieto)
|
|
84
|
+
|
|
85
|
+
- Updated dependencies [[`6d067665562223ce2865f1c14be54b0b50258bd4`](https://github.com/Shopify/hydrogen/commit/6d067665562223ce2865f1c14be54b0b50258bd4), [`d57782a1ae3fa0017836d6010fb6ac5ab5d25965`](https://github.com/Shopify/hydrogen/commit/d57782a1ae3fa0017836d6010fb6ac5ab5d25965), [`48cbd450699a29a5667bee7174f3856430508ecc`](https://github.com/Shopify/hydrogen/commit/48cbd450699a29a5667bee7174f3856430508ecc), [`6d067665562223ce2865f1c14be54b0b50258bd4`](https://github.com/Shopify/hydrogen/commit/6d067665562223ce2865f1c14be54b0b50258bd4), [`0b4f01c9aa0e09332140a6a4e3114949873fb0f9`](https://github.com/Shopify/hydrogen/commit/0b4f01c9aa0e09332140a6a4e3114949873fb0f9), [`0d165ff280692411712176427bcd7e0df43b56fe`](https://github.com/Shopify/hydrogen/commit/0d165ff280692411712176427bcd7e0df43b56fe), [`ae7bedc89c1968b4a035f421b5ee6908f6376b1b`](https://github.com/Shopify/hydrogen/commit/ae7bedc89c1968b4a035f421b5ee6908f6376b1b), [`ae7bedc89c1968b4a035f421b5ee6908f6376b1b`](https://github.com/Shopify/hydrogen/commit/ae7bedc89c1968b4a035f421b5ee6908f6376b1b), [`75623a5bfdd8d6f0eab0d3547860341c20d9076c`](https://github.com/Shopify/hydrogen/commit/75623a5bfdd8d6f0eab0d3547860341c20d9076c), [`6681f92e84d42b5a6aca153fb49e31dcd8af84f6`](https://github.com/Shopify/hydrogen/commit/6681f92e84d42b5a6aca153fb49e31dcd8af84f6), [`4daf37ea291334b23bd543fdad5673ab7c9a6133`](https://github.com/Shopify/hydrogen/commit/4daf37ea291334b23bd543fdad5673ab7c9a6133)]:
|
|
86
|
+
- @shopify/hydrogen@2026.0.0
|
|
87
|
+
|
|
88
|
+
## 2025.5.2
|
|
89
|
+
|
|
90
|
+
### Patch Changes
|
|
91
|
+
|
|
92
|
+
- Fixing the skeleton's Vite Config ([#2958](https://github.com/Shopify/hydrogen/pull/2958)) by [@balazsbajorics](https://github.com/balazsbajorics)
|
|
93
|
+
|
|
94
|
+
## 2025.5.1
|
|
95
|
+
|
|
96
|
+
### Patch Changes
|
|
97
|
+
|
|
98
|
+
- Bumping the cli to 3.80.4 ([#2956](https://github.com/Shopify/hydrogen/pull/2956)) by [@balazsbajorics](https://github.com/balazsbajorics)
|
|
99
|
+
|
|
3
100
|
## 2025.5.0
|
|
4
101
|
|
|
5
102
|
### Patch Changes
|
|
@@ -28,7 +125,6 @@
|
|
|
28
125
|
### Patch Changes
|
|
29
126
|
|
|
30
127
|
- Fix an issue with our starter template where duplicate content can exist on URLs that use internationalized handles. For example, if you have a product handle in english of `the-havoc` and translate it to `das-chaos` in German, duplicate content exists at both: ([#2821](https://github.com/Shopify/hydrogen/pull/2821)) by [@blittle](https://github.com/blittle)
|
|
31
|
-
|
|
32
128
|
1. https://hydrogen.shop/de-de/products/das-chaos
|
|
33
129
|
2. https://hydrogen.shop/de-de/products/the-havoc
|
|
34
130
|
|
|
@@ -48,7 +144,6 @@
|
|
|
48
144
|
### Patch Changes
|
|
49
145
|
|
|
50
146
|
- Moved the `Layout` component back into `root.tsx` to avoid issues with styled errors. ([#2829](https://github.com/Shopify/hydrogen/pull/2829)) by [@ruggishop](https://github.com/ruggishop)
|
|
51
|
-
|
|
52
147
|
1. If you have a separate `app/layout.tsx` file, delete it and move its default exported component into your `root.tsx`. For example:
|
|
53
148
|
|
|
54
149
|
```ts
|
|
@@ -102,7 +197,6 @@
|
|
|
102
197
|
- Support for the Remix future flag `v3_routeConfig`. ([#2722](https://github.com/Shopify/hydrogen/pull/2722)) by [@seanparsons](https://github.com/seanparsons)
|
|
103
198
|
|
|
104
199
|
Please refer to the Remix documentation for more details on `v3_routeConfig` future flag: [https://remix.run/docs/en/main/start/future-flags#v3_routeconfig](https://remix.run/docs/en/main/start/future-flags#v3_routeconfig)
|
|
105
|
-
|
|
106
200
|
1. Update your `vite.config.ts`.
|
|
107
201
|
|
|
108
202
|
```diff
|
|
@@ -197,7 +291,6 @@
|
|
|
197
291
|
Remix single fetch migration guide: https://remix.run/docs/en/main/guides/single-fetch
|
|
198
292
|
|
|
199
293
|
**Note:** If you have any routes that appends (or looks for) a search param named `_data`, make sure to rename it to something else.
|
|
200
|
-
|
|
201
294
|
1. In your `vite.config.ts`, add the single fetch future flag.
|
|
202
295
|
|
|
203
296
|
```diff
|
|
@@ -495,7 +588,6 @@
|
|
|
495
588
|
- Remove initial redirect from product display page ([#2643](https://github.com/Shopify/hydrogen/pull/2643)) by [@scottdixon](https://github.com/scottdixon)
|
|
496
589
|
|
|
497
590
|
- Optional updates for the product route and product form to handle combined listing and 2000 variant limit. ([#2659](https://github.com/Shopify/hydrogen/pull/2659)) by [@wizardlyhel](https://github.com/wizardlyhel)
|
|
498
|
-
|
|
499
591
|
1. Update your SFAPI product query to bring in the new query fields:
|
|
500
592
|
|
|
501
593
|
```diff
|
|
@@ -1307,7 +1399,6 @@
|
|
|
1307
1399
|
### Patch Changes
|
|
1308
1400
|
|
|
1309
1401
|
- Stabilize `getSitemap`, `getSitemapIndex` and implement on skeleton ([#2589](https://github.com/Shopify/hydrogen/pull/2589)) by [@juanpprieto](https://github.com/juanpprieto)
|
|
1310
|
-
|
|
1311
1402
|
1. Update the `getSitemapIndex` at `/app/routes/[sitemap.xml].tsx`
|
|
1312
1403
|
|
|
1313
1404
|
```diff
|
|
@@ -1417,7 +1508,6 @@
|
|
|
1417
1508
|
- [**Breaking change**] ([#2585](https://github.com/Shopify/hydrogen/pull/2585)) by [@wizardlyhel](https://github.com/wizardlyhel)
|
|
1418
1509
|
|
|
1419
1510
|
Deprecate usages of `product.options.values` and use `product.options.optionValues` instead.
|
|
1420
|
-
|
|
1421
1511
|
1. Update your product graphql query to use the new `optionValues` field.
|
|
1422
1512
|
|
|
1423
1513
|
```diff
|
|
@@ -2098,7 +2188,6 @@
|
|
|
2098
2188
|
### Patch Changes
|
|
2099
2189
|
|
|
2100
2190
|
- Improve performance of predictive search: ([#1823](https://github.com/Shopify/hydrogen/pull/1823)) by [@frandiox](https://github.com/frandiox)
|
|
2101
|
-
|
|
2102
2191
|
- Change the request to be GET instead of POST to avoid Remix route revalidations.
|
|
2103
2192
|
- Add Cache-Control headers to the response to get quicker results when typing.
|
|
2104
2193
|
|
|
@@ -2318,7 +2407,6 @@
|
|
|
2318
2407
|
### Major Changes
|
|
2319
2408
|
|
|
2320
2409
|
- The Storefront API 2023-10 now returns menu item URLs that include the `primaryDomainUrl`, instead of defaulting to the Shopify store ID URL (example.myshopify.com). The skeleton template requires changes to check for the `primaryDomainUrl`: by [@blittle](https://github.com/blittle)
|
|
2321
|
-
|
|
2322
2410
|
1. Update the `HeaderMenu` component to accept a `primaryDomainUrl` and include
|
|
2323
2411
|
it in the internal url check
|
|
2324
2412
|
|
|
@@ -2,7 +2,7 @@ import type {CartLineUpdateInput} from '@shopify/hydrogen/storefront-api-types';
|
|
|
2
2
|
import type {CartLayout} from '~/components/CartMain';
|
|
3
3
|
import {CartForm, Image, type OptimisticCartLine} from '@shopify/hydrogen';
|
|
4
4
|
import {useVariantUrl} from '~/lib/variants';
|
|
5
|
-
import {
|
|
5
|
+
import {Link} from 'react-router';
|
|
6
6
|
import {ProductPrice} from './ProductPrice';
|
|
7
7
|
import {useAside} from './Aside';
|
|
8
8
|
import type {CartApiQueryFragment} from 'storefrontapi.generated';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {useOptimisticCart} from '@shopify/hydrogen';
|
|
2
|
-
import {
|
|
2
|
+
import {Link} from 'react-router';
|
|
3
3
|
import type {CartApiQueryFragment} from 'storefrontapi.generated';
|
|
4
4
|
import {useAside} from '~/components/Aside';
|
|
5
5
|
import {CartLineItem} from '~/components/CartLineItem';
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type {CartApiQueryFragment} from 'storefrontapi.generated';
|
|
2
2
|
import type {CartLayout} from '~/components/CartMain';
|
|
3
3
|
import {CartForm, Money, type OptimisticCart} from '@shopify/hydrogen';
|
|
4
|
-
import {useRef} from 'react';
|
|
5
|
-
import {
|
|
4
|
+
import {useEffect, useRef} from 'react';
|
|
5
|
+
import {useFetcher} from 'react-router';
|
|
6
|
+
import type {FetcherWithComponents} from 'react-router';
|
|
6
7
|
|
|
7
8
|
type CartSummaryProps = {
|
|
8
9
|
cart: OptimisticCart<CartApiQueryFragment | null>;
|
|
@@ -19,19 +20,20 @@ export function CartSummary({cart, layout}: CartSummaryProps) {
|
|
|
19
20
|
<dl className="cart-subtotal">
|
|
20
21
|
<dt>Subtotal</dt>
|
|
21
22
|
<dd>
|
|
22
|
-
{cart
|
|
23
|
-
<Money data={cart
|
|
23
|
+
{cart?.cost?.subtotalAmount?.amount ? (
|
|
24
|
+
<Money data={cart?.cost?.subtotalAmount} />
|
|
24
25
|
) : (
|
|
25
26
|
'-'
|
|
26
27
|
)}
|
|
27
28
|
</dd>
|
|
28
29
|
</dl>
|
|
29
|
-
<CartDiscounts discountCodes={cart
|
|
30
|
-
<CartGiftCard giftCardCodes={cart
|
|
31
|
-
<CartCheckoutActions checkoutUrl={cart
|
|
30
|
+
<CartDiscounts discountCodes={cart?.discountCodes} />
|
|
31
|
+
<CartGiftCard giftCardCodes={cart?.appliedGiftCards} />
|
|
32
|
+
<CartCheckoutActions checkoutUrl={cart?.checkoutUrl} />
|
|
32
33
|
</div>
|
|
33
34
|
);
|
|
34
35
|
}
|
|
36
|
+
|
|
35
37
|
function CartCheckoutActions({checkoutUrl}: {checkoutUrl?: string}) {
|
|
36
38
|
if (!checkoutUrl) return null;
|
|
37
39
|
|
|
@@ -110,41 +112,47 @@ function CartGiftCard({
|
|
|
110
112
|
}) {
|
|
111
113
|
const appliedGiftCardCodes = useRef<string[]>([]);
|
|
112
114
|
const giftCardCodeInput = useRef<HTMLInputElement>(null);
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
+
const giftCardAddFetcher = useFetcher({key: 'gift-card-add'});
|
|
116
|
+
|
|
117
|
+
// Clear the gift card code input after the gift card is added
|
|
118
|
+
useEffect(() => {
|
|
119
|
+
if (giftCardAddFetcher.data) {
|
|
120
|
+
giftCardCodeInput.current!.value = '';
|
|
121
|
+
}
|
|
122
|
+
}, [giftCardAddFetcher.data]);
|
|
115
123
|
|
|
116
124
|
function saveAppliedCode(code: string) {
|
|
117
125
|
const formattedCode = code.replace(/\s/g, ''); // Remove spaces
|
|
118
126
|
if (!appliedGiftCardCodes.current.includes(formattedCode)) {
|
|
119
127
|
appliedGiftCardCodes.current.push(formattedCode);
|
|
120
128
|
}
|
|
121
|
-
giftCardCodeInput.current!.value = '';
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
function removeAppliedCode() {
|
|
125
|
-
appliedGiftCardCodes.current = [];
|
|
126
129
|
}
|
|
127
130
|
|
|
128
131
|
return (
|
|
129
132
|
<div>
|
|
130
|
-
{/*
|
|
131
|
-
|
|
132
|
-
<
|
|
133
|
+
{/* Display applied gift cards with individual remove buttons */}
|
|
134
|
+
{giftCardCodes && giftCardCodes.length > 0 && (
|
|
135
|
+
<dl>
|
|
133
136
|
<dt>Applied Gift Card(s)</dt>
|
|
134
|
-
|
|
135
|
-
<
|
|
136
|
-
<
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
137
|
+
{giftCardCodes.map((giftCard) => (
|
|
138
|
+
<RemoveGiftCardForm key={giftCard.id} giftCardId={giftCard.id}>
|
|
139
|
+
<div className="cart-discount">
|
|
140
|
+
<code>***{giftCard.lastCharacters}</code>
|
|
141
|
+
|
|
142
|
+
<Money data={giftCard.amountUsed} />
|
|
143
|
+
|
|
144
|
+
<button type="submit">Remove</button>
|
|
145
|
+
</div>
|
|
146
|
+
</RemoveGiftCardForm>
|
|
147
|
+
))}
|
|
148
|
+
</dl>
|
|
149
|
+
)}
|
|
143
150
|
|
|
144
|
-
{/* Show an input to apply a
|
|
151
|
+
{/* Show an input to apply a gift card */}
|
|
145
152
|
<UpdateGiftCardForm
|
|
146
153
|
giftCardCodes={appliedGiftCardCodes.current}
|
|
147
154
|
saveAppliedCode={saveAppliedCode}
|
|
155
|
+
fetcherKey="gift-card-add"
|
|
148
156
|
>
|
|
149
157
|
<div>
|
|
150
158
|
<input
|
|
@@ -154,7 +162,9 @@ function CartGiftCard({
|
|
|
154
162
|
ref={giftCardCodeInput}
|
|
155
163
|
/>
|
|
156
164
|
|
|
157
|
-
<button type="submit">
|
|
165
|
+
<button type="submit" disabled={giftCardAddFetcher.state !== 'idle'}>
|
|
166
|
+
Apply
|
|
167
|
+
</button>
|
|
158
168
|
</div>
|
|
159
169
|
</UpdateGiftCardForm>
|
|
160
170
|
</div>
|
|
@@ -164,15 +174,17 @@ function CartGiftCard({
|
|
|
164
174
|
function UpdateGiftCardForm({
|
|
165
175
|
giftCardCodes,
|
|
166
176
|
saveAppliedCode,
|
|
177
|
+
fetcherKey,
|
|
167
178
|
children,
|
|
168
179
|
}: {
|
|
169
180
|
giftCardCodes?: string[];
|
|
170
181
|
saveAppliedCode?: (code: string) => void;
|
|
171
|
-
|
|
182
|
+
fetcherKey?: string;
|
|
172
183
|
children: React.ReactNode;
|
|
173
184
|
}) {
|
|
174
185
|
return (
|
|
175
186
|
<CartForm
|
|
187
|
+
fetcherKey={fetcherKey}
|
|
176
188
|
route="/cart"
|
|
177
189
|
action={CartForm.ACTIONS.GiftCardCodesUpdate}
|
|
178
190
|
inputs={{
|
|
@@ -189,3 +201,24 @@ function UpdateGiftCardForm({
|
|
|
189
201
|
</CartForm>
|
|
190
202
|
);
|
|
191
203
|
}
|
|
204
|
+
|
|
205
|
+
function RemoveGiftCardForm({
|
|
206
|
+
giftCardId,
|
|
207
|
+
children,
|
|
208
|
+
}: {
|
|
209
|
+
giftCardId: string;
|
|
210
|
+
children: React.ReactNode;
|
|
211
|
+
}) {
|
|
212
|
+
return (
|
|
213
|
+
<CartForm
|
|
214
|
+
route="/cart"
|
|
215
|
+
action={CartForm.ACTIONS.GiftCardCodesRemove}
|
|
216
|
+
inputs={{
|
|
217
|
+
giftCardCodes: [giftCardId],
|
|
218
|
+
}}
|
|
219
|
+
>
|
|
220
|
+
{children}
|
|
221
|
+
</CartForm>
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {Link, useNavigate} from 'react-router';
|
|
2
2
|
import {type MappedProductOptions} from '@shopify/hydrogen';
|
|
3
3
|
import type {
|
|
4
4
|
Maybe,
|
|
@@ -84,7 +84,7 @@ export function ProductForm({
|
|
|
84
84
|
disabled={!exists}
|
|
85
85
|
onClick={() => {
|
|
86
86
|
if (!selected) {
|
|
87
|
-
navigate(`?${variantUriQuery}`, {
|
|
87
|
+
void navigate(`?${variantUriQuery}`, {
|
|
88
88
|
replace: true,
|
|
89
89
|
preventScrollReset: true,
|
|
90
90
|
});
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
useFetcher,
|
|
3
|
+
useNavigate,
|
|
4
|
+
type FormProps,
|
|
5
|
+
type Fetcher,
|
|
6
|
+
} from 'react-router';
|
|
2
7
|
import React, {useRef, useEffect} from 'react';
|
|
3
8
|
import type {PredictiveSearchReturn} from '~/lib/search';
|
|
4
9
|
import {useAside} from './Aside';
|
|
@@ -41,13 +46,13 @@ export function SearchFormPredictive({
|
|
|
41
46
|
/** Navigate to the search page with the current input value */
|
|
42
47
|
function goToSearch() {
|
|
43
48
|
const term = inputRef?.current?.value;
|
|
44
|
-
navigate(SEARCH_ENDPOINT + (term ? `?q=${term}` : ''));
|
|
49
|
+
void navigate(SEARCH_ENDPOINT + (term ? `?q=${term}` : ''));
|
|
45
50
|
aside.close();
|
|
46
51
|
}
|
|
47
52
|
|
|
48
53
|
/** Fetch search results based on the input value */
|
|
49
54
|
function fetchResults(event: React.ChangeEvent<HTMLInputElement>) {
|
|
50
|
-
fetcher.submit(
|
|
55
|
+
void fetcher.submit(
|
|
51
56
|
{q: event.target.value || '', limit: 5, predictive: true},
|
|
52
57
|
{method: 'GET', action: SEARCH_ENDPOINT},
|
|
53
58
|
);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {Link} from 'react-router';
|
|
2
2
|
import {Image, Money, Pagination} from '@shopify/hydrogen';
|
|
3
3
|
import {urlWithTrackingParams, type RegularSearchReturn} from '~/lib/search';
|
|
4
4
|
|
|
@@ -120,19 +120,11 @@ function SearchResultsProducts({
|
|
|
120
120
|
<div className="search-results-item" key={product.id}>
|
|
121
121
|
<Link prefetch="intent" to={productUrl}>
|
|
122
122
|
{image && (
|
|
123
|
-
<Image
|
|
124
|
-
data={image}
|
|
125
|
-
alt={product.title}
|
|
126
|
-
width={50}
|
|
127
|
-
/>
|
|
123
|
+
<Image data={image} alt={product.title} width={50} />
|
|
128
124
|
)}
|
|
129
125
|
<div>
|
|
130
126
|
<p>{product.title}</p>
|
|
131
|
-
<small>
|
|
132
|
-
{price &&
|
|
133
|
-
<Money data={price} />
|
|
134
|
-
}
|
|
135
|
-
</small>
|
|
127
|
+
<small>{price && <Money data={price} />}</small>
|
|
136
128
|
</div>
|
|
137
129
|
</Link>
|
|
138
130
|
</div>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {Link, useFetcher, type Fetcher} from 'react-router';
|
|
2
2
|
import {Image, Money} from '@shopify/hydrogen';
|
|
3
3
|
import React, {useRef, useEffect} from 'react';
|
|
4
4
|
import {
|
|
@@ -228,11 +228,7 @@ function SearchResultsPredictiveProducts({
|
|
|
228
228
|
)}
|
|
229
229
|
<div>
|
|
230
230
|
<p>{product.title}</p>
|
|
231
|
-
<small>
|
|
232
|
-
{price && (
|
|
233
|
-
<Money data={price} />
|
|
234
|
-
)}
|
|
235
|
-
</small>
|
|
231
|
+
<small>{price && <Money data={price} />}</small>
|
|
236
232
|
</div>
|
|
237
233
|
</Link>
|
|
238
234
|
</li>
|
|
@@ -1,13 +1,21 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {HydratedRouter} from 'react-router/dom';
|
|
2
2
|
import {startTransition, StrictMode} from 'react';
|
|
3
3
|
import {hydrateRoot} from 'react-dom/client';
|
|
4
|
+
import {NonceProvider} from '@shopify/hydrogen';
|
|
4
5
|
|
|
5
6
|
if (!window.location.origin.includes('webcache.googleusercontent.com')) {
|
|
6
7
|
startTransition(() => {
|
|
8
|
+
// Extract nonce from existing script tags
|
|
9
|
+
const existingNonce = document
|
|
10
|
+
.querySelector<HTMLScriptElement>('script[nonce]')
|
|
11
|
+
?.nonce;
|
|
12
|
+
|
|
7
13
|
hydrateRoot(
|
|
8
14
|
document,
|
|
9
15
|
<StrictMode>
|
|
10
|
-
<
|
|
16
|
+
<NonceProvider value={existingNonce}>
|
|
17
|
+
<HydratedRouter />
|
|
18
|
+
</NonceProvider>
|
|
11
19
|
</StrictMode>,
|
|
12
20
|
);
|
|
13
21
|
});
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import type {AppLoadContext} from '@shopify/remix-oxygen';
|
|
2
1
|
import {ServerRouter} from 'react-router';
|
|
3
2
|
import {isbot} from 'isbot';
|
|
4
3
|
import {renderToReadableStream} from 'react-dom/server';
|
|
5
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
createContentSecurityPolicy,
|
|
6
|
+
type HydrogenRouterContextProvider,
|
|
7
|
+
} from '@shopify/hydrogen';
|
|
6
8
|
import type {EntryContext} from 'react-router';
|
|
7
9
|
|
|
8
10
|
export default async function handleRequest(
|
|
@@ -10,7 +12,7 @@ export default async function handleRequest(
|
|
|
10
12
|
responseStatusCode: number,
|
|
11
13
|
responseHeaders: Headers,
|
|
12
14
|
reactRouterContext: EntryContext,
|
|
13
|
-
context:
|
|
15
|
+
context: HydrogenRouterContextProvider,
|
|
14
16
|
) {
|
|
15
17
|
const {nonce, header, NonceProvider} = createContentSecurityPolicy({
|
|
16
18
|
shop: {
|
package/dist/assets/hydrogen/starter/app/graphql/customer-account/CustomerAddressMutations.ts
CHANGED
|
@@ -4,7 +4,8 @@ export const UPDATE_ADDRESS_MUTATION = `#graphql
|
|
|
4
4
|
$address: CustomerAddressInput!
|
|
5
5
|
$addressId: ID!
|
|
6
6
|
$defaultAddress: Boolean
|
|
7
|
-
|
|
7
|
+
$language: LanguageCode
|
|
8
|
+
) @inContext(language: $language) {
|
|
8
9
|
customerAddressUpdate(
|
|
9
10
|
address: $address
|
|
10
11
|
addressId: $addressId
|
|
@@ -25,8 +26,9 @@ export const UPDATE_ADDRESS_MUTATION = `#graphql
|
|
|
25
26
|
// NOTE: https://shopify.dev/docs/api/customer/latest/mutations/customerAddressDelete
|
|
26
27
|
export const DELETE_ADDRESS_MUTATION = `#graphql
|
|
27
28
|
mutation customerAddressDelete(
|
|
28
|
-
$addressId: ID
|
|
29
|
-
|
|
29
|
+
$addressId: ID!
|
|
30
|
+
$language: LanguageCode
|
|
31
|
+
) @inContext(language: $language) {
|
|
30
32
|
customerAddressDelete(addressId: $addressId) {
|
|
31
33
|
deletedAddressId
|
|
32
34
|
userErrors {
|
|
@@ -43,7 +45,8 @@ export const CREATE_ADDRESS_MUTATION = `#graphql
|
|
|
43
45
|
mutation customerAddressCreate(
|
|
44
46
|
$address: CustomerAddressInput!
|
|
45
47
|
$defaultAddress: Boolean
|
|
46
|
-
|
|
48
|
+
$language: LanguageCode
|
|
49
|
+
) @inContext(language: $language) {
|
|
47
50
|
customerAddressCreate(
|
|
48
51
|
address: $address
|
|
49
52
|
defaultAddress: $defaultAddress
|
|
@@ -31,7 +31,7 @@ export const CUSTOMER_FRAGMENT = `#graphql
|
|
|
31
31
|
|
|
32
32
|
// NOTE: https://shopify.dev/docs/api/customer/latest/queries/customer
|
|
33
33
|
export const CUSTOMER_DETAILS_QUERY = `#graphql
|
|
34
|
-
query CustomerDetails {
|
|
34
|
+
query CustomerDetails($language: LanguageCode) @inContext(language: $language) {
|
|
35
35
|
customer {
|
|
36
36
|
...Customer
|
|
37
37
|
}
|
|
@@ -45,7 +45,9 @@ export const CUSTOMER_ORDER_QUERY = `#graphql
|
|
|
45
45
|
fragment Order on Order {
|
|
46
46
|
id
|
|
47
47
|
name
|
|
48
|
+
confirmationNumber
|
|
48
49
|
statusPageUrl
|
|
50
|
+
fulfillmentStatus
|
|
49
51
|
processedAt
|
|
50
52
|
fulfillments(first: 1) {
|
|
51
53
|
nodes {
|
|
@@ -77,7 +79,8 @@ export const CUSTOMER_ORDER_QUERY = `#graphql
|
|
|
77
79
|
}
|
|
78
80
|
}
|
|
79
81
|
}
|
|
80
|
-
query Order($orderId: ID
|
|
82
|
+
query Order($orderId: ID!, $language: LanguageCode)
|
|
83
|
+
@inContext(language: $language) {
|
|
81
84
|
order(id: $orderId) {
|
|
82
85
|
... on Order {
|
|
83
86
|
...Order
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// https://shopify.dev/docs/api/customer/latest/objects/Order
|
|
1
|
+
// NOTE: https://shopify.dev/docs/api/customer/latest/objects/Order
|
|
2
2
|
export const ORDER_ITEM_FRAGMENT = `#graphql
|
|
3
3
|
fragment OrderItem on Order {
|
|
4
4
|
totalPrice {
|
|
@@ -6,6 +6,7 @@ export const ORDER_ITEM_FRAGMENT = `#graphql
|
|
|
6
6
|
currencyCode
|
|
7
7
|
}
|
|
8
8
|
financialStatus
|
|
9
|
+
fulfillmentStatus
|
|
9
10
|
fulfillments(first: 1) {
|
|
10
11
|
nodes {
|
|
11
12
|
status
|
|
@@ -13,11 +14,12 @@ export const ORDER_ITEM_FRAGMENT = `#graphql
|
|
|
13
14
|
}
|
|
14
15
|
id
|
|
15
16
|
number
|
|
17
|
+
confirmationNumber
|
|
16
18
|
processedAt
|
|
17
19
|
}
|
|
18
20
|
` as const;
|
|
19
21
|
|
|
20
|
-
// https://shopify.dev/docs/api/customer/latest/objects/Customer
|
|
22
|
+
// NOTE: https://shopify.dev/docs/api/customer/latest/objects/Customer
|
|
21
23
|
export const CUSTOMER_ORDERS_FRAGMENT = `#graphql
|
|
22
24
|
fragment CustomerOrders on Customer {
|
|
23
25
|
orders(
|
|
@@ -26,7 +28,8 @@ export const CUSTOMER_ORDERS_FRAGMENT = `#graphql
|
|
|
26
28
|
first: $first,
|
|
27
29
|
last: $last,
|
|
28
30
|
before: $startCursor,
|
|
29
|
-
after: $endCursor
|
|
31
|
+
after: $endCursor,
|
|
32
|
+
query: $query
|
|
30
33
|
) {
|
|
31
34
|
nodes {
|
|
32
35
|
...OrderItem
|
|
@@ -42,7 +45,7 @@ export const CUSTOMER_ORDERS_FRAGMENT = `#graphql
|
|
|
42
45
|
${ORDER_ITEM_FRAGMENT}
|
|
43
46
|
` as const;
|
|
44
47
|
|
|
45
|
-
// https://shopify.dev/docs/api/customer/latest/queries/customer
|
|
48
|
+
// NOTE: https://shopify.dev/docs/api/customer/latest/queries/customer
|
|
46
49
|
export const CUSTOMER_ORDERS_QUERY = `#graphql
|
|
47
50
|
${CUSTOMER_ORDERS_FRAGMENT}
|
|
48
51
|
query CustomerOrders(
|
|
@@ -50,7 +53,9 @@ export const CUSTOMER_ORDERS_QUERY = `#graphql
|
|
|
50
53
|
$first: Int
|
|
51
54
|
$last: Int
|
|
52
55
|
$startCursor: String
|
|
53
|
-
|
|
56
|
+
$query: String
|
|
57
|
+
$language: LanguageCode
|
|
58
|
+
) @inContext(language: $language) {
|
|
54
59
|
customer {
|
|
55
60
|
...CustomerOrders
|
|
56
61
|
}
|