@shopify/cli 3.75.1 → 3.75.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.
Files changed (116) hide show
  1. package/dist/assets/hydrogen/starter/CHANGELOG.md +206 -0
  2. package/dist/assets/hydrogen/starter/app/components/CartMain.tsx +1 -1
  3. package/dist/assets/hydrogen/starter/app/components/CartSummary.tsx +17 -6
  4. package/dist/assets/hydrogen/starter/app/entry.server.tsx +2 -3
  5. package/dist/assets/hydrogen/starter/app/root.tsx +9 -5
  6. package/dist/assets/hydrogen/starter/app/routes/[robots.txt].tsx +0 -1
  7. package/dist/assets/hydrogen/starter/app/routes/_index.tsx +2 -2
  8. package/dist/assets/hydrogen/starter/app/routes/account.addresses.tsx +17 -17
  9. package/dist/assets/hydrogen/starter/app/routes/account.orders.$id.tsx +3 -3
  10. package/dist/assets/hydrogen/starter/app/routes/account.orders._index.tsx +2 -2
  11. package/dist/assets/hydrogen/starter/app/routes/account.profile.tsx +6 -6
  12. package/dist/assets/hydrogen/starter/app/routes/account.tsx +2 -2
  13. package/dist/assets/hydrogen/starter/app/routes/blogs.$blogHandle.$articleHandle.tsx +2 -2
  14. package/dist/assets/hydrogen/starter/app/routes/blogs.$blogHandle._index.tsx +2 -2
  15. package/dist/assets/hydrogen/starter/app/routes/blogs._index.tsx +2 -2
  16. package/dist/assets/hydrogen/starter/app/routes/cart.tsx +5 -3
  17. package/dist/assets/hydrogen/starter/app/routes/collections.$handle.tsx +2 -2
  18. package/dist/assets/hydrogen/starter/app/routes/collections._index.tsx +2 -2
  19. package/dist/assets/hydrogen/starter/app/routes/collections.all.tsx +2 -2
  20. package/dist/assets/hydrogen/starter/app/routes/pages.$handle.tsx +2 -2
  21. package/dist/assets/hydrogen/starter/app/routes/policies.$handle.tsx +2 -2
  22. package/dist/assets/hydrogen/starter/app/routes/policies._index.tsx +2 -2
  23. package/dist/assets/hydrogen/starter/app/routes/products.$handle.tsx +2 -2
  24. package/dist/assets/hydrogen/starter/app/routes/search.tsx +1 -2
  25. package/dist/assets/hydrogen/starter/eslint.config.js +261 -0
  26. package/dist/assets/hydrogen/starter/guides/predictiveSearch/predictiveSearch.md +3 -3
  27. package/dist/assets/hydrogen/starter/guides/search/search.md +3 -3
  28. package/dist/assets/hydrogen/starter/package.json +24 -12
  29. package/dist/assets/hydrogen/starter/server.ts +3 -2
  30. package/dist/assets/hydrogen/starter/tsconfig.json +5 -1
  31. package/dist/assets/hydrogen/starter/vite.config.ts +7 -0
  32. package/dist/assets/hydrogen/vite/package.json +1 -1
  33. package/dist/assets/hydrogen/vite/vite.config.js +0 -1
  34. package/dist/{chunk-DXX7H2IH.js → chunk-22VHHB6E.js} +3 -3
  35. package/dist/{chunk-FGC2O2I5.js → chunk-2NZ7C43W.js} +6 -6
  36. package/dist/{chunk-FTFTFTDU.js → chunk-33Y36JTQ.js} +3 -3
  37. package/dist/{chunk-U673QDO3.js → chunk-3QMRSRBQ.js} +2 -2
  38. package/dist/{chunk-IRNTKQVQ.js → chunk-5R65XQBB.js} +3 -3
  39. package/dist/{chunk-7CQUOSVH.js → chunk-5U5CBWN6.js} +6 -6
  40. package/dist/{chunk-5CJ7VYH7.js → chunk-A2VS5S6I.js} +2 -2
  41. package/dist/{chunk-LJHVF5TJ.js → chunk-B5KBQUD7.js} +3 -3
  42. package/dist/{chunk-MTPFCNYB.js → chunk-BI6OG3SW.js} +3 -3
  43. package/dist/{chunk-YEOP3EMX.js → chunk-C33FHDOM.js} +2 -2
  44. package/dist/{chunk-H3VLXETQ.js → chunk-CM7HYAXG.js} +2 -2
  45. package/dist/{chunk-IEEXWVOL.js → chunk-EIDXBYRF.js} +2 -2
  46. package/dist/{chunk-PDZHLRZ2.js → chunk-FNGSPBMI.js} +7 -7
  47. package/dist/{chunk-IMWIHPKY.js → chunk-G4AWJOUT.js} +3 -3
  48. package/dist/{chunk-ORGKANED.js → chunk-G4WKRFAA.js} +3 -3
  49. package/dist/{chunk-UYZDNGSJ.js → chunk-GXE74MLK.js} +2 -2
  50. package/dist/{chunk-7HSAZRHC.js → chunk-IKLIMBXL.js} +3 -3
  51. package/dist/{chunk-IHA7JJN4.js → chunk-JTBKPH2T.js} +2 -2
  52. package/dist/{chunk-4EZQAZ74.js → chunk-K4H4V3DT.js} +6 -6
  53. package/dist/{chunk-VSC4NMYT.js → chunk-KD3XBFOR.js} +2 -2
  54. package/dist/{chunk-CV5T4LOB.js → chunk-KTZUTNES.js} +3 -3
  55. package/dist/{chunk-PB3V422W.js → chunk-LCLDLGWN.js} +5 -5
  56. package/dist/{chunk-KR2ZEBN3.js → chunk-LZMNVVKL.js} +4 -4
  57. package/dist/{chunk-245U5NQK.js → chunk-MAEFXTUW.js} +4 -4
  58. package/dist/{chunk-S3NMVYAF.js → chunk-MW2DSTSP.js} +4 -4
  59. package/dist/{chunk-JS6RLMBK.js → chunk-OV2HTJBT.js} +3 -3
  60. package/dist/{chunk-Y5RMFD7I.js → chunk-PD5FJTJV.js} +3 -3
  61. package/dist/{chunk-4MJNU2QF.js → chunk-QGVSI72K.js} +3 -3
  62. package/dist/{chunk-2TEPYAPA.js → chunk-QODWZ6PQ.js} +3 -3
  63. package/dist/{chunk-P654UJXI.js → chunk-RR6KDBGU.js} +5 -5
  64. package/dist/{chunk-63Z76ANM.js → chunk-USS26MJN.js} +2 -2
  65. package/dist/{chunk-7OOACYZ4.js → chunk-VJRNACS6.js} +3 -3
  66. package/dist/{chunk-NA34VFTA.js → chunk-WMN57UOI.js} +76 -76
  67. package/dist/{chunk-SXT3JFLA.js → chunk-WZLRLCYA.js} +4 -4
  68. package/dist/{chunk-UEEQNXRY.js → chunk-YFC422QN.js} +3 -3
  69. package/dist/{chunk-ZJSUUIVI.js → chunk-YJQB4KNO.js} +3 -3
  70. package/dist/cli/commands/auth/logout.js +12 -12
  71. package/dist/cli/commands/auth/logout.test.js +13 -13
  72. package/dist/cli/commands/cache/clear.js +11 -11
  73. package/dist/cli/commands/debug/command-flags.js +11 -11
  74. package/dist/cli/commands/docs/generate.js +11 -11
  75. package/dist/cli/commands/docs/generate.test.js +11 -11
  76. package/dist/cli/commands/help.js +11 -11
  77. package/dist/cli/commands/kitchen-sink/async.js +12 -12
  78. package/dist/cli/commands/kitchen-sink/async.test.js +12 -12
  79. package/dist/cli/commands/kitchen-sink/index.js +14 -14
  80. package/dist/cli/commands/kitchen-sink/index.test.js +14 -14
  81. package/dist/cli/commands/kitchen-sink/prompts.js +12 -12
  82. package/dist/cli/commands/kitchen-sink/prompts.test.js +12 -12
  83. package/dist/cli/commands/kitchen-sink/static.js +12 -12
  84. package/dist/cli/commands/kitchen-sink/static.test.js +12 -12
  85. package/dist/cli/commands/notifications/generate.js +12 -12
  86. package/dist/cli/commands/notifications/list.js +12 -12
  87. package/dist/cli/commands/search.js +12 -12
  88. package/dist/cli/commands/upgrade.js +12 -12
  89. package/dist/cli/commands/version.js +12 -12
  90. package/dist/cli/commands/version.test.js +12 -12
  91. package/dist/cli/services/commands/notifications.js +6 -6
  92. package/dist/cli/services/commands/search.js +2 -2
  93. package/dist/cli/services/commands/search.test.js +2 -2
  94. package/dist/cli/services/commands/version.js +3 -3
  95. package/dist/cli/services/commands/version.test.js +4 -4
  96. package/dist/cli/services/kitchen-sink/async.js +2 -2
  97. package/dist/cli/services/kitchen-sink/prompts.js +2 -2
  98. package/dist/cli/services/kitchen-sink/static.js +2 -2
  99. package/dist/cli/services/upgrade.js +3 -3
  100. package/dist/cli/services/upgrade.test.js +5 -5
  101. package/dist/{custom-oclif-loader-5N4JRQ46.js → custom-oclif-loader-T46YXHAL.js} +2 -2
  102. package/dist/{error-handler-VQHDL26P.js → error-handler-CQQM6XL7.js} +9 -9
  103. package/dist/hooks/postrun.js +7 -7
  104. package/dist/hooks/prerun.js +7 -7
  105. package/dist/index.js +119 -119
  106. package/dist/{local-NKJECUJ3.js → local-UIVNM7TY.js} +2 -2
  107. package/dist/{morph-BTANDGVW.js → morph-K3QSNZNW.js} +9 -9
  108. package/dist/{node-RIZFDTN7.js → node-Y5CCPBME.js} +15 -15
  109. package/dist/{node-package-manager-EOSRJYAN.js → node-package-manager-LYGJUDK2.js} +3 -3
  110. package/dist/tsconfig.tsbuildinfo +1 -1
  111. package/dist/{ui-II7LUT5P.js → ui-6CY7AHOT.js} +2 -2
  112. package/dist/{workerd-SKOXR5SE.js → workerd-S3A3XU2A.js} +14 -14
  113. package/oclif.manifest.json +1 -1
  114. package/package.json +7 -7
  115. package/dist/assets/hydrogen/starter/.eslintignore +0 -5
  116. package/dist/assets/hydrogen/starter/.eslintrc.cjs +0 -19
@@ -1,5 +1,211 @@
1
1
  # skeleton
2
2
 
3
+ ## 2025.1.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Upgrade eslint to version 9 and unify eslint config across all packages (with the exception of the skeleton, which still keeps its own config) ([#2716](https://github.com/Shopify/hydrogen/pull/2716)) by [@liady](https://github.com/liady)
8
+
9
+ - Bump remix version ([#2740](https://github.com/Shopify/hydrogen/pull/2740)) by [@wizardlyhel](https://github.com/wizardlyhel)
10
+
11
+ - Turn on Remix `v3_singleFetch` future flag ([#2708](https://github.com/Shopify/hydrogen/pull/2708)) by [@wizardlyhel](https://github.com/wizardlyhel)
12
+
13
+ Remix single fetch migration quick guide: https://remix.run/docs/en/main/start/future-flags#v3_singlefetch
14
+ Remix single fetch migration guide: https://remix.run/docs/en/main/guides/single-fetch
15
+
16
+ **Note:** If you have any routes that appends (or looks for) a search param named `_data`, make sure to rename it to something else.
17
+
18
+ 1. In your `vite.config.ts`, add the single fetch future flag.
19
+
20
+ ```diff
21
+ + declare module "@remix-run/server-runtime" {
22
+ + interface Future {
23
+ + v3_singleFetch: true;
24
+ + }
25
+ + }
26
+
27
+ export default defineConfig({
28
+ plugins: [
29
+ hydrogen(),
30
+ oxygen(),
31
+ remix({
32
+ presets: [hydrogen.preset()],
33
+ future: {
34
+ v3_fetcherPersist: true,
35
+ v3_relativeSplatPath: true,
36
+ v3_throwAbortReason: true,
37
+ v3_lazyRouteDiscovery: true,
38
+ + v3_singleFetch: true,
39
+ },
40
+ }),
41
+ tsconfigPaths(),
42
+ ],
43
+ ```
44
+
45
+ 2. In your `entry.server.tsx`, add `nonce` to the `<RemixServer>`.
46
+
47
+ ```diff
48
+ const body = await renderToReadableStream(
49
+ <NonceProvider>
50
+ <RemixServer
51
+ context={remixContext}
52
+ url={request.url}
53
+ + nonce={nonce}
54
+ />
55
+ </NonceProvider>,
56
+ ```
57
+
58
+ 3. Update the `shouldRevalidate` function in `root.tsx`.
59
+
60
+ Defaulting to no revalidation for root loader data to improve performance. When using this feature, you risk your UI getting out of sync with your server. Use with caution. If you are uncomfortable with this optimization, update the `return false;` to `return defaultShouldRevalidate;` instead.
61
+
62
+ For more details see: https://remix.run/docs/en/main/route/should-revalidate
63
+
64
+ ```diff
65
+ export const shouldRevalidate: ShouldRevalidateFunction = ({
66
+ formMethod,
67
+ currentUrl,
68
+ nextUrl,
69
+ - defaultShouldRevalidate,
70
+ }) => {
71
+ // revalidate when a mutation is performed e.g add to cart, login...
72
+ if (formMethod && formMethod !== 'GET') return true;
73
+
74
+ // revalidate when manually revalidating via useRevalidator
75
+ if (currentUrl.toString() === nextUrl.toString()) return true;
76
+
77
+ - return defaultShouldRevalidate;
78
+ + return false;
79
+ };
80
+ ```
81
+
82
+ 4. Update `cart.tsx` to add a headers export and update to `data` import usage.
83
+
84
+ ```diff
85
+ import {
86
+ - json,
87
+ + data,
88
+ type LoaderFunctionArgs,
89
+ type ActionFunctionArgs,
90
+ type HeadersFunction
91
+ } from '@shopify/remix-oxygen';
92
+ + export const headers: HeadersFunction = ({actionHeaders}) => actionHeaders;
93
+
94
+ export async function action({request, context}: ActionFunctionArgs) {
95
+ ...
96
+ - return json(
97
+ + return data(
98
+ {
99
+ cart: cartResult,
100
+ errors,
101
+ warnings,
102
+ analytics: {
103
+ cartId,
104
+ },
105
+ },
106
+ {status, headers},
107
+ );
108
+ }
109
+
110
+ export async function loader({context}: LoaderFunctionArgs) {
111
+ const {cart} = context;
112
+ - return json(await cart.get());
113
+ + return await cart.get();
114
+ }
115
+ ```
116
+
117
+ 5. Deprecate `json` and `defer` import usage from `@shopify/remix-oxygen`.
118
+
119
+ Remove `json()`/`defer()` in favor of raw objects.
120
+
121
+ Single Fetch supports JSON objects and Promises out of the box, so you can return the raw data from your loader/action functions:
122
+
123
+ ```diff
124
+ - import {json} from "@shopify/remix-oxygen";
125
+
126
+ export async function loader({}: LoaderFunctionArgs) {
127
+ let tasks = await fetchTasks();
128
+ - return json(tasks);
129
+ + return tasks;
130
+ }
131
+ ```
132
+
133
+ ```diff
134
+ - import {defer} from "@shopify/remix-oxygen";
135
+
136
+ export async function loader({}: LoaderFunctionArgs) {
137
+ let lazyStuff = fetchLazyStuff();
138
+ let tasks = await fetchTasks();
139
+ - return defer({ tasks, lazyStuff });
140
+ + return { tasks, lazyStuff };
141
+ }
142
+ ```
143
+
144
+ If you were using the second parameter of json/defer to set a custom status or headers on your response, you can continue doing so via the new data API:
145
+
146
+ ```diff
147
+ - import {json} from "@shopify/remix-oxygen";
148
+ + import {data, type HeadersFunction} from "@shopify/remix-oxygen";
149
+
150
+ + /**
151
+ + * If your loader or action is returning a response with headers,
152
+ + * make sure to export a headers function that merges your headers
153
+ + * on your route. Otherwise, your headers may be lost.
154
+ + * Remix doc: https://remix.run/docs/en/main/route/headers
155
+ + **/
156
+ + export const headers: HeadersFunction = ({loaderHeaders}) => loaderHeaders;
157
+
158
+ export async function loader({}: LoaderFunctionArgs) {
159
+ let tasks = await fetchTasks();
160
+ - return json(tasks, {
161
+ + return data(tasks, {
162
+ headers: {
163
+ "Cache-Control": "public, max-age=604800"
164
+ }
165
+ });
166
+ }
167
+ ```
168
+
169
+ 6. If you are using legacy customer account flow or multipass, there are a couple more files that requires updating:
170
+
171
+ In `root.tsx` and `routes/account.tsx`, add a `headers` export for `loaderHeaders`.
172
+
173
+ ```diff
174
+ + export const headers: HeadersFunction = ({loaderHeaders}) => loaderHeaders;
175
+ ```
176
+
177
+ In `routes/account_.register.tsx`, add a `headers` export for `actionHeaders`.
178
+
179
+ ```diff
180
+ + export const headers: HeadersFunction = ({actionHeaders}) => actionHeaders;
181
+ ```
182
+
183
+ 7. If you are using multipass, in `routes/account_.login.multipass.tsx`
184
+
185
+ a. export a `headers` export
186
+
187
+ ```diff
188
+ + export const headers: HeadersFunction = ({actionHeaders}) => actionHeaders;
189
+ ```
190
+
191
+ b. Update all `json` response wrapper to `remixData`
192
+
193
+ ```diff
194
+ import {
195
+ - json,
196
+ + data as remixData,
197
+ } from '@shopify/remix-oxygen';
198
+
199
+ - return json(
200
+ + return remixData(
201
+ ...
202
+ );
203
+ ```
204
+
205
+ - Updated dependencies [[`3af2e453`](https://github.com/Shopify/hydrogen/commit/3af2e4534eafe1467f70a35885a2fa2ef7724fa8), [`6bff6b62`](https://github.com/Shopify/hydrogen/commit/6bff6b6260af21b8025426c7031ab862dbecbc34), [`cd65685c`](https://github.com/Shopify/hydrogen/commit/cd65685c1036233faaead0330f25183900b102a7), [`8c717570`](https://github.com/Shopify/hydrogen/commit/8c7175701d9f4dd05d271ea46b6ab40d6e3210cb), [`4e81bd1b`](https://github.com/Shopify/hydrogen/commit/4e81bd1b0e99b5c760679b565d2f95c4fc15b934), [`3ea25820`](https://github.com/Shopify/hydrogen/commit/3ea25820b0b0094d982e481782e413165435cf00)]:
206
+ - @shopify/hydrogen@2025.1.1
207
+ - @shopify/remix-oxygen@2.0.11
208
+
3
209
  ## 2025.1.0
4
210
 
5
211
  ### Patch Changes
@@ -26,7 +26,7 @@ export function CartMain({layout, cart: originalCart}: CartMainProps) {
26
26
  cart &&
27
27
  Boolean(cart?.discountCodes?.filter((code) => code.applicable)?.length);
28
28
  const className = `cart-main ${withDiscount ? 'with-discount' : ''}`;
29
- const cartHasItems = cart?.totalQuantity! > 0;
29
+ const cartHasItems = cart?.totalQuantity && cart?.totalQuantity > 0;
30
30
 
31
31
  return (
32
32
  <div className={className}>
@@ -1,8 +1,8 @@
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 { FetcherWithComponents } from '@remix-run/react';
4
+ import {useRef} from 'react';
5
+ import {FetcherWithComponents} from '@remix-run/react';
6
6
 
7
7
  type CartSummaryProps = {
8
8
  cart: OptimisticCart<CartApiQueryFragment | null>;
@@ -110,7 +110,8 @@ function CartGiftCard({
110
110
  }) {
111
111
  const appliedGiftCardCodes = useRef<string[]>([]);
112
112
  const giftCardCodeInput = useRef<HTMLInputElement>(null);
113
- const codes: string[] = giftCardCodes?.map(({lastCharacters}) => `***${lastCharacters}`) || [];
113
+ const codes: string[] =
114
+ giftCardCodes?.map(({lastCharacters}) => `***${lastCharacters}`) || [];
114
115
 
115
116
  function saveAppliedCode(code: string) {
116
117
  const formattedCode = code.replace(/\s/g, ''); // Remove spaces
@@ -141,9 +142,17 @@ function CartGiftCard({
141
142
  </dl>
142
143
 
143
144
  {/* Show an input to apply a discount */}
144
- <UpdateGiftCardForm giftCardCodes={appliedGiftCardCodes.current} saveAppliedCode={saveAppliedCode}>
145
+ <UpdateGiftCardForm
146
+ giftCardCodes={appliedGiftCardCodes.current}
147
+ saveAppliedCode={saveAppliedCode}
148
+ >
145
149
  <div>
146
- <input type="text" name="giftCardCode" placeholder="Gift card code" ref={giftCardCodeInput} />
150
+ <input
151
+ type="text"
152
+ name="giftCardCode"
153
+ placeholder="Gift card code"
154
+ ref={giftCardCodeInput}
155
+ />
147
156
  &nbsp;
148
157
  <button type="submit">Apply</button>
149
158
  </div>
@@ -172,7 +181,9 @@ function UpdateGiftCardForm({
172
181
  >
173
182
  {(fetcher: FetcherWithComponents<any>) => {
174
183
  const code = fetcher.formData?.get('giftCardCode');
175
- if (code) saveAppliedCode && saveAppliedCode(code as string);
184
+ if (code && saveAppliedCode) {
185
+ saveAppliedCode(code as string);
186
+ }
176
187
  return children;
177
188
  }}
178
189
  </CartForm>
@@ -1,6 +1,6 @@
1
1
  import type {EntryContext, AppLoadContext} from '@shopify/remix-oxygen';
2
2
  import {RemixServer} from '@remix-run/react';
3
- import isbot from 'isbot';
3
+ import {isbot} from 'isbot';
4
4
  import {renderToReadableStream} from 'react-dom/server';
5
5
  import {createContentSecurityPolicy} from '@shopify/hydrogen';
6
6
 
@@ -20,13 +20,12 @@ export default async function handleRequest(
20
20
 
21
21
  const body = await renderToReadableStream(
22
22
  <NonceProvider>
23
- <RemixServer context={remixContext} url={request.url} />
23
+ <RemixServer context={remixContext} url={request.url} nonce={nonce}/>
24
24
  </NonceProvider>,
25
25
  {
26
26
  nonce,
27
27
  signal: request.signal,
28
28
  onError(error) {
29
- // eslint-disable-next-line no-console
30
29
  console.error(error);
31
30
  responseStatusCode = 500;
32
31
  },
@@ -1,5 +1,5 @@
1
1
  import {useNonce, getShopAnalytics, Analytics} from '@shopify/hydrogen';
2
- import {defer, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
2
+ import {type LoaderFunctionArgs} from '@shopify/remix-oxygen';
3
3
  import {
4
4
  Links,
5
5
  Meta,
@@ -26,7 +26,6 @@ export const shouldRevalidate: ShouldRevalidateFunction = ({
26
26
  formMethod,
27
27
  currentUrl,
28
28
  nextUrl,
29
- defaultShouldRevalidate,
30
29
  }) => {
31
30
  // revalidate when a mutation is performed e.g add to cart, login...
32
31
  if (formMethod && formMethod !== 'GET') return true;
@@ -34,7 +33,12 @@ export const shouldRevalidate: ShouldRevalidateFunction = ({
34
33
  // revalidate when manually revalidating via useRevalidator
35
34
  if (currentUrl.toString() === nextUrl.toString()) return true;
36
35
 
37
- return defaultShouldRevalidate;
36
+ // Defaulting to no revalidation for root loader data to improve performance.
37
+ // When using this feature, you risk your UI getting out of sync with your server.
38
+ // Use with caution. If you are uncomfortable with this optimization, update the
39
+ // line below to `return defaultShouldRevalidate` instead.
40
+ // For more details see: https://remix.run/docs/en/main/route/should-revalidate
41
+ return false;
38
42
  };
39
43
 
40
44
  /**
@@ -70,7 +74,7 @@ export async function loader(args: LoaderFunctionArgs) {
70
74
 
71
75
  const {storefront, env} = args.context;
72
76
 
73
- return defer({
77
+ return {
74
78
  ...deferredData,
75
79
  ...criticalData,
76
80
  publicStoreDomain: env.PUBLIC_STORE_DOMAIN,
@@ -86,7 +90,7 @@ export async function loader(args: LoaderFunctionArgs) {
86
90
  country: args.context.storefront.i18n.country,
87
91
  language: args.context.storefront.i18n.language,
88
92
  },
89
- });
93
+ };
90
94
  }
91
95
 
92
96
  /**
@@ -1,5 +1,4 @@
1
1
  import {type LoaderFunctionArgs} from '@shopify/remix-oxygen';
2
- import {useRouteError, isRouteErrorResponse} from '@remix-run/react';
3
2
  import {parseGid} from '@shopify/hydrogen';
4
3
 
5
4
  export async function loader({request, context}: LoaderFunctionArgs) {
@@ -1,4 +1,4 @@
1
- import {defer, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
1
+ import {type LoaderFunctionArgs} from '@shopify/remix-oxygen';
2
2
  import {Await, useLoaderData, Link, type MetaFunction} from '@remix-run/react';
3
3
  import {Suspense} from 'react';
4
4
  import {Image, Money} from '@shopify/hydrogen';
@@ -18,7 +18,7 @@ export async function loader(args: LoaderFunctionArgs) {
18
18
  // Await the critical data required to render initial state of the page
19
19
  const criticalData = await loadCriticalData(args);
20
20
 
21
- return defer({...deferredData, ...criticalData});
21
+ return {...deferredData, ...criticalData};
22
22
  }
23
23
 
24
24
  /**
@@ -4,7 +4,7 @@ import type {
4
4
  CustomerFragment,
5
5
  } from 'customer-accountapi.generated';
6
6
  import {
7
- json,
7
+ data,
8
8
  type ActionFunctionArgs,
9
9
  type LoaderFunctionArgs,
10
10
  } from '@shopify/remix-oxygen';
@@ -38,7 +38,7 @@ export const meta: MetaFunction = () => {
38
38
  export async function loader({context}: LoaderFunctionArgs) {
39
39
  await context.customerAccount.handleAuthStatus();
40
40
 
41
- return json({});
41
+ return {};
42
42
  }
43
43
 
44
44
  export async function action({request, context}: ActionFunctionArgs) {
@@ -57,7 +57,7 @@ export async function action({request, context}: ActionFunctionArgs) {
57
57
  // this will ensure redirecting to login never happen for mutatation
58
58
  const isLoggedIn = await customerAccount.isLoggedIn();
59
59
  if (!isLoggedIn) {
60
- return json(
60
+ return data(
61
61
  {error: {[addressId]: 'Unauthorized'}},
62
62
  {
63
63
  status: 401,
@@ -112,21 +112,21 @@ export async function action({request, context}: ActionFunctionArgs) {
112
112
  throw new Error('Customer address create failed.');
113
113
  }
114
114
 
115
- return json({
115
+ return {
116
116
  error: null,
117
117
  createdAddress: data?.customerAddressCreate?.customerAddress,
118
118
  defaultAddress,
119
- });
119
+ };
120
120
  } catch (error: unknown) {
121
121
  if (error instanceof Error) {
122
- return json(
122
+ return data(
123
123
  {error: {[addressId]: error.message}},
124
124
  {
125
125
  status: 400,
126
126
  },
127
127
  );
128
128
  }
129
- return json(
129
+ return data(
130
130
  {error: {[addressId]: error}},
131
131
  {
132
132
  status: 400,
@@ -161,21 +161,21 @@ export async function action({request, context}: ActionFunctionArgs) {
161
161
  throw new Error('Customer address update failed.');
162
162
  }
163
163
 
164
- return json({
164
+ return {
165
165
  error: null,
166
166
  updatedAddress: address,
167
167
  defaultAddress,
168
- });
168
+ };
169
169
  } catch (error: unknown) {
170
170
  if (error instanceof Error) {
171
- return json(
171
+ return data(
172
172
  {error: {[addressId]: error.message}},
173
173
  {
174
174
  status: 400,
175
175
  },
176
176
  );
177
177
  }
178
- return json(
178
+ return data(
179
179
  {error: {[addressId]: error}},
180
180
  {
181
181
  status: 400,
@@ -206,17 +206,17 @@ export async function action({request, context}: ActionFunctionArgs) {
206
206
  throw new Error('Customer address delete failed.');
207
207
  }
208
208
 
209
- return json({error: null, deletedAddress: addressId});
209
+ return {error: null, deletedAddress: addressId};
210
210
  } catch (error: unknown) {
211
211
  if (error instanceof Error) {
212
- return json(
212
+ return data(
213
213
  {error: {[addressId]: error.message}},
214
214
  {
215
215
  status: 400,
216
216
  },
217
217
  );
218
218
  }
219
- return json(
219
+ return data(
220
220
  {error: {[addressId]: error}},
221
221
  {
222
222
  status: 400,
@@ -226,7 +226,7 @@ export async function action({request, context}: ActionFunctionArgs) {
226
226
  }
227
227
 
228
228
  default: {
229
- return json(
229
+ return data(
230
230
  {error: {[addressId]: 'Method not allowed'}},
231
231
  {
232
232
  status: 405,
@@ -236,14 +236,14 @@ export async function action({request, context}: ActionFunctionArgs) {
236
236
  }
237
237
  } catch (error: unknown) {
238
238
  if (error instanceof Error) {
239
- return json(
239
+ return data(
240
240
  {error: error.message},
241
241
  {
242
242
  status: 400,
243
243
  },
244
244
  );
245
245
  }
246
- return json(
246
+ return data(
247
247
  {error},
248
248
  {
249
249
  status: 400,
@@ -1,4 +1,4 @@
1
- import {json, redirect, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
1
+ import {redirect, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
2
2
  import {useLoaderData, type MetaFunction} from '@remix-run/react';
3
3
  import {Money, Image, flattenConnection} from '@shopify/hydrogen';
4
4
  import type {OrderLineItemFullFragment} from 'customer-accountapi.generated';
@@ -42,13 +42,13 @@ export async function loader({params, context}: LoaderFunctionArgs) {
42
42
  firstDiscount?.__typename === 'PricingPercentageValue' &&
43
43
  firstDiscount?.percentage;
44
44
 
45
- return json({
45
+ return {
46
46
  order,
47
47
  lineItems,
48
48
  discountValue,
49
49
  discountPercentage,
50
50
  fulfillmentStatus,
51
- });
51
+ };
52
52
  }
53
53
 
54
54
  export default function OrderRoute() {
@@ -4,7 +4,7 @@ import {
4
4
  getPaginationVariables,
5
5
  flattenConnection,
6
6
  } from '@shopify/hydrogen';
7
- import {json, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
7
+ import {type LoaderFunctionArgs} from '@shopify/remix-oxygen';
8
8
  import {CUSTOMER_ORDERS_QUERY} from '~/graphql/customer-account/CustomerOrdersQuery';
9
9
  import type {
10
10
  CustomerOrdersFragment,
@@ -34,7 +34,7 @@ export async function loader({request, context}: LoaderFunctionArgs) {
34
34
  throw Error('Customer orders not found');
35
35
  }
36
36
 
37
- return json({customer: data.customer});
37
+ return {customer: data.customer};
38
38
  }
39
39
 
40
40
  export default function Orders() {
@@ -2,7 +2,7 @@ import type {CustomerFragment} from 'customer-accountapi.generated';
2
2
  import type {CustomerUpdateInput} from '@shopify/hydrogen/customer-account-api-types';
3
3
  import {CUSTOMER_UPDATE_MUTATION} from '~/graphql/customer-account/CustomerUpdateMutation';
4
4
  import {
5
- json,
5
+ data,
6
6
  type ActionFunctionArgs,
7
7
  type LoaderFunctionArgs,
8
8
  } from '@shopify/remix-oxygen';
@@ -26,14 +26,14 @@ export const meta: MetaFunction = () => {
26
26
  export async function loader({context}: LoaderFunctionArgs) {
27
27
  await context.customerAccount.handleAuthStatus();
28
28
 
29
- return json({});
29
+ return {};
30
30
  }
31
31
 
32
32
  export async function action({request, context}: ActionFunctionArgs) {
33
33
  const {customerAccount} = context;
34
34
 
35
35
  if (request.method !== 'PUT') {
36
- return json({error: 'Method not allowed'}, {status: 405});
36
+ return data({error: 'Method not allowed'}, {status: 405});
37
37
  }
38
38
 
39
39
  const form = await request.formData();
@@ -68,12 +68,12 @@ export async function action({request, context}: ActionFunctionArgs) {
68
68
  throw new Error('Customer profile update failed.');
69
69
  }
70
70
 
71
- return json({
71
+ return {
72
72
  error: null,
73
73
  customer: data?.customerUpdate?.customer,
74
- });
74
+ };
75
75
  } catch (error: any) {
76
- return json(
76
+ return data(
77
77
  {error: error.message, customer: null},
78
78
  {
79
79
  status: 400,
@@ -1,4 +1,4 @@
1
- import {json, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
1
+ import {data as remixData, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
2
2
  import {Form, NavLink, Outlet, useLoaderData} from '@remix-run/react';
3
3
  import {CUSTOMER_DETAILS_QUERY} from '~/graphql/customer-account/CustomerDetailsQuery';
4
4
 
@@ -15,7 +15,7 @@ export async function loader({context}: LoaderFunctionArgs) {
15
15
  throw new Error('Customer not found');
16
16
  }
17
17
 
18
- return json(
18
+ return remixData(
19
19
  {customer: data.customer},
20
20
  {
21
21
  headers: {
@@ -1,4 +1,4 @@
1
- import {defer, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
1
+ import {type LoaderFunctionArgs} from '@shopify/remix-oxygen';
2
2
  import {useLoaderData, type MetaFunction} from '@remix-run/react';
3
3
  import {Image} from '@shopify/hydrogen';
4
4
 
@@ -13,7 +13,7 @@ export async function loader(args: LoaderFunctionArgs) {
13
13
  // Await the critical data required to render initial state of the page
14
14
  const criticalData = await loadCriticalData(args);
15
15
 
16
- return defer({...deferredData, ...criticalData});
16
+ return {...deferredData, ...criticalData};
17
17
  }
18
18
 
19
19
  /**
@@ -1,4 +1,4 @@
1
- import {defer, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
1
+ import {type LoaderFunctionArgs} from '@shopify/remix-oxygen';
2
2
  import {Link, useLoaderData, type MetaFunction} from '@remix-run/react';
3
3
  import {Image, getPaginationVariables} from '@shopify/hydrogen';
4
4
  import type {ArticleItemFragment} from 'storefrontapi.generated';
@@ -15,7 +15,7 @@ export async function loader(args: LoaderFunctionArgs) {
15
15
  // Await the critical data required to render initial state of the page
16
16
  const criticalData = await loadCriticalData(args);
17
17
 
18
- return defer({...deferredData, ...criticalData});
18
+ return {...deferredData, ...criticalData};
19
19
  }
20
20
 
21
21
  /**
@@ -1,4 +1,4 @@
1
- import {defer, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
1
+ import {type LoaderFunctionArgs} from '@shopify/remix-oxygen';
2
2
  import {Link, useLoaderData, type MetaFunction} from '@remix-run/react';
3
3
  import {getPaginationVariables} from '@shopify/hydrogen';
4
4
  import {PaginatedResourceSection} from '~/components/PaginatedResourceSection';
@@ -14,7 +14,7 @@ export async function loader(args: LoaderFunctionArgs) {
14
14
  // Await the critical data required to render initial state of the page
15
15
  const criticalData = await loadCriticalData(args);
16
16
 
17
- return defer({...deferredData, ...criticalData});
17
+ return {...deferredData, ...criticalData};
18
18
  }
19
19
 
20
20
  /**
@@ -1,13 +1,15 @@
1
1
  import {type MetaFunction, useLoaderData} from '@remix-run/react';
2
2
  import type {CartQueryDataReturn} from '@shopify/hydrogen';
3
3
  import {CartForm} from '@shopify/hydrogen';
4
- import {json, type LoaderFunctionArgs, type ActionFunctionArgs} from '@shopify/remix-oxygen';
4
+ import {data, type LoaderFunctionArgs, type ActionFunctionArgs, type HeadersFunction} from '@shopify/remix-oxygen';
5
5
  import {CartMain} from '~/components/CartMain';
6
6
 
7
7
  export const meta: MetaFunction = () => {
8
8
  return [{title: `Hydrogen | Cart`}];
9
9
  };
10
10
 
11
+ export const headers: HeadersFunction = ({actionHeaders}) => actionHeaders;
12
+
11
13
  export async function action({request, context}: ActionFunctionArgs) {
12
14
  const {cart} = context;
13
15
 
@@ -80,7 +82,7 @@ export async function action({request, context}: ActionFunctionArgs) {
80
82
  headers.set('Location', redirectTo);
81
83
  }
82
84
 
83
- return json(
85
+ return data(
84
86
  {
85
87
  cart: cartResult,
86
88
  errors,
@@ -95,7 +97,7 @@ export async function action({request, context}: ActionFunctionArgs) {
95
97
 
96
98
  export async function loader({context}: LoaderFunctionArgs) {
97
99
  const {cart} = context;
98
- return json(await cart.get());
100
+ return await cart.get();
99
101
  }
100
102
 
101
103
  export default function Cart() {