@shopify/hydrogen 0.17.2 → 0.19.0

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 (161) hide show
  1. package/CHANGELOG.md +209 -0
  2. package/config.js +1 -0
  3. package/dist/esnext/client.d.ts +2 -0
  4. package/dist/esnext/client.js +2 -0
  5. package/dist/esnext/components/AddToCartButton/AddToCartButton.client.js +2 -2
  6. package/dist/esnext/components/CartProvider/CartProvider.client.js +15 -14
  7. package/dist/esnext/components/CartProvider/{hooks.d.ts → hooks.client.d.ts} +0 -0
  8. package/dist/esnext/components/CartProvider/{hooks.js → hooks.client.js} +0 -0
  9. package/dist/esnext/components/CartProvider/index.d.ts +1 -1
  10. package/dist/esnext/components/CartProvider/index.js +1 -1
  11. package/dist/esnext/components/{DevTools.d.ts → DevTools.client.d.ts} +0 -0
  12. package/dist/esnext/components/{DevTools.js → DevTools.client.js} +3 -2
  13. package/dist/esnext/components/Image/Image.d.ts +6 -0
  14. package/dist/esnext/components/Image/Image.js +8 -3
  15. package/dist/esnext/components/Link/Link.client.js +11 -2
  16. package/dist/esnext/components/LocalizationProvider/LocalizationClientProvider.client.js +2 -15
  17. package/dist/esnext/components/LocalizationProvider/LocalizationContext.client.d.ts +0 -1
  18. package/dist/esnext/components/LocalizationProvider/LocalizationProvider.server.d.ts +2 -6
  19. package/dist/esnext/components/LocalizationProvider/LocalizationProvider.server.js +11 -5
  20. package/dist/esnext/components/Metafield/Metafield.client.js +4 -5
  21. package/dist/esnext/components/ModelViewer/ModelViewer.client.js +1 -1
  22. package/dist/esnext/components/Money/Money.client.d.ts +5 -1
  23. package/dist/esnext/components/Money/Money.client.js +16 -3
  24. package/dist/esnext/components/ProductMetafield/ProductMetafield.client.js +1 -1
  25. package/dist/esnext/components/ProductProvider/ProductOptionsProvider.client.js +1 -1
  26. package/dist/esnext/components/ProductProvider/ProductProvider.client.d.ts +7 -3
  27. package/dist/esnext/components/ProductProvider/ProductProvider.client.js +1 -1
  28. package/dist/esnext/components/ShopPayButton/ShopPayButton.client.js +6 -2
  29. package/dist/esnext/components/Video/Video.js +3 -1
  30. package/dist/esnext/config.d.ts +3 -0
  31. package/dist/esnext/config.js +1 -0
  32. package/dist/esnext/constants.js +1 -1
  33. package/dist/esnext/entry-client.js +3 -1
  34. package/dist/esnext/entry-server.d.ts +2 -2
  35. package/dist/esnext/entry-server.js +56 -82
  36. package/dist/esnext/foundation/Analytics/ClientAnalytics.d.ts +1 -0
  37. package/dist/esnext/foundation/Analytics/ClientAnalytics.js +7 -1
  38. package/dist/esnext/foundation/Analytics/connectors/PerformanceMetrics/PerformanceMetrics.client.d.ts +7 -0
  39. package/dist/esnext/foundation/Analytics/connectors/PerformanceMetrics/PerformanceMetrics.client.js +64 -0
  40. package/dist/esnext/foundation/Analytics/connectors/PerformanceMetrics/PerformanceMetrics.server.d.ts +1 -0
  41. package/dist/esnext/foundation/Analytics/connectors/PerformanceMetrics/PerformanceMetrics.server.js +24 -0
  42. package/dist/esnext/foundation/Analytics/connectors/PerformanceMetrics/PerformanceMetricsDebug.client.d.ts +1 -0
  43. package/dist/esnext/foundation/Analytics/connectors/PerformanceMetrics/PerformanceMetricsDebug.client.js +23 -0
  44. package/dist/esnext/foundation/Analytics/const.d.ts +1 -0
  45. package/dist/esnext/foundation/Analytics/const.js +1 -0
  46. package/dist/esnext/foundation/Cookie/Cookie.js +2 -1
  47. package/dist/esnext/foundation/FileRoutes/FileRoutes.server.d.ts +4 -4
  48. package/dist/esnext/foundation/FileRoutes/FileRoutes.server.js +17 -4
  49. package/dist/esnext/foundation/FileSessionStorage/FileSessionStorage.js +2 -1
  50. package/dist/esnext/foundation/Redirect/Redirect.client.js +1 -0
  51. package/dist/esnext/foundation/Route/Route.server.js +1 -10
  52. package/dist/esnext/foundation/Router/BrowserRouter.client.js +10 -1
  53. package/dist/esnext/foundation/ServerPropsProvider/ServerPropsProvider.js +5 -3
  54. package/dist/esnext/foundation/ServerRequestProvider/ServerRequestProvider.d.ts +2 -2
  55. package/dist/esnext/foundation/ServerRequestProvider/ServerRequestProvider.js +7 -2
  56. package/dist/esnext/foundation/ServerStateProvider/ServerStateProvider.js +8 -1
  57. package/dist/esnext/foundation/ShopifyProvider/ShopifyProvider.server.d.ts +8 -1
  58. package/dist/esnext/foundation/ShopifyProvider/ShopifyProvider.server.js +31 -5
  59. package/dist/esnext/foundation/ShopifyProvider/types.d.ts +3 -4
  60. package/dist/esnext/foundation/fetchSync/client/fetchSync.js +2 -1
  61. package/dist/esnext/foundation/fetchSync/server/fetchSync.js +4 -2
  62. package/dist/esnext/foundation/ssr-interop.js +1 -1
  63. package/dist/esnext/foundation/useQuery/hooks.d.ts +1 -1
  64. package/dist/esnext/foundation/useQuery/hooks.js +2 -2
  65. package/dist/esnext/foundation/useSession/useSession.d.ts +1 -1
  66. package/dist/esnext/foundation/useSession/useSession.js +1 -1
  67. package/dist/esnext/foundation/useShop/use-shop.d.ts +3 -1
  68. package/dist/esnext/foundation/useShop/use-shop.js +3 -1
  69. package/dist/esnext/foundation/useUrl/useUrl.js +7 -4
  70. package/dist/esnext/framework/Hydration/Html.js +1 -1
  71. package/dist/esnext/framework/Hydration/ServerComponentRequest.server.d.ts +3 -2
  72. package/dist/esnext/framework/Hydration/ServerComponentRequest.server.js +16 -7
  73. package/dist/esnext/framework/Hydration/rsc.d.ts +0 -3
  74. package/dist/esnext/framework/Hydration/rsc.js +0 -20
  75. package/dist/esnext/framework/middleware.d.ts +3 -4
  76. package/dist/esnext/framework/middleware.js +4 -4
  77. package/dist/esnext/framework/plugin.d.ts +2 -2
  78. package/dist/esnext/framework/plugin.js +3 -3
  79. package/dist/esnext/framework/plugins/vite-plugin-hydrogen-config.js +1 -1
  80. package/dist/esnext/framework/plugins/vite-plugin-hydrogen-middleware.d.ts +2 -2
  81. package/dist/esnext/framework/plugins/vite-plugin-hydrogen-middleware.js +59 -4
  82. package/dist/esnext/hooks/useCountry/useCountry.d.ts +1 -11
  83. package/dist/esnext/hooks/useCountry/useCountry.js +1 -1
  84. package/dist/esnext/hooks/useLoadScript/index.d.ts +1 -1
  85. package/dist/esnext/hooks/useLoadScript/index.js +1 -1
  86. package/dist/esnext/hooks/useLoadScript/{useLoadScript.d.ts → useLoadScript.client.d.ts} +0 -0
  87. package/dist/esnext/hooks/useLoadScript/{useLoadScript.js → useLoadScript.client.js} +2 -1
  88. package/dist/esnext/hooks/useMoney/hooks.d.ts +13 -1
  89. package/dist/esnext/hooks/useMoney/hooks.js +25 -1
  90. package/dist/esnext/hooks/useParsedMetafields/useParsedMetafields.js +0 -2
  91. package/dist/esnext/hooks/useProduct/useProduct.js +1 -1
  92. package/dist/esnext/hooks/useProductOptions/index.d.ts +1 -1
  93. package/dist/esnext/hooks/useProductOptions/index.js +1 -1
  94. package/dist/esnext/hooks/useProductOptions/{useProductOptions.d.ts → useProductOptions.client.d.ts} +0 -0
  95. package/dist/esnext/hooks/useProductOptions/{useProductOptions.js → useProductOptions.client.js} +6 -23
  96. package/dist/esnext/hooks/useShopQuery/hooks.js +15 -4
  97. package/dist/esnext/index.d.ts +1 -0
  98. package/dist/esnext/index.js +1 -0
  99. package/dist/esnext/node.d.ts +1 -0
  100. package/dist/esnext/node.js +1 -0
  101. package/dist/esnext/storefront-api-types.d.ts +60 -6
  102. package/dist/esnext/storefront-api-types.js +6 -2
  103. package/dist/esnext/types.d.ts +11 -4
  104. package/dist/esnext/utilities/apiRoutes.d.ts +4 -4
  105. package/dist/esnext/utilities/apiRoutes.js +29 -16
  106. package/dist/esnext/utilities/bot-ua.js +4 -0
  107. package/dist/esnext/utilities/empty-hydrogen-config.d.ts +2 -0
  108. package/dist/esnext/utilities/empty-hydrogen-config.js +2 -0
  109. package/dist/esnext/utilities/findRoutePrefix.d.ts +1 -0
  110. package/dist/esnext/utilities/findRoutePrefix.js +17 -0
  111. package/dist/esnext/utilities/log/utils.js +1 -1
  112. package/dist/esnext/utilities/parse.d.ts +1 -0
  113. package/dist/esnext/utilities/parse.js +9 -0
  114. package/dist/esnext/utilities/parseMetafieldValue/parseMetafieldValue.js +2 -1
  115. package/dist/esnext/utilities/storefrontApi.js +1 -0
  116. package/dist/esnext/version.d.ts +1 -1
  117. package/dist/esnext/version.js +1 -1
  118. package/dist/node/constants.js +1 -1
  119. package/dist/node/entry-server.d.ts +2 -2
  120. package/dist/node/entry-server.js +56 -82
  121. package/dist/node/foundation/Analytics/ClientAnalytics.d.ts +1 -0
  122. package/dist/node/foundation/Analytics/ClientAnalytics.js +7 -1
  123. package/dist/node/foundation/Analytics/const.d.ts +1 -0
  124. package/dist/node/foundation/Analytics/const.js +1 -0
  125. package/dist/node/foundation/Redirect/Redirect.client.js +1 -0
  126. package/dist/node/foundation/Router/BrowserRouter.client.js +10 -1
  127. package/dist/node/foundation/ServerPropsProvider/ServerPropsProvider.js +5 -3
  128. package/dist/node/foundation/ServerRequestProvider/ServerRequestProvider.d.ts +2 -2
  129. package/dist/node/foundation/ServerRequestProvider/ServerRequestProvider.js +7 -2
  130. package/dist/node/foundation/ShopifyProvider/types.d.ts +3 -4
  131. package/dist/node/foundation/ssr-interop.js +1 -1
  132. package/dist/node/framework/Hydration/Html.js +1 -1
  133. package/dist/node/framework/Hydration/ServerComponentRequest.server.d.ts +3 -2
  134. package/dist/node/framework/Hydration/ServerComponentRequest.server.js +16 -7
  135. package/dist/node/framework/Hydration/rsc.d.ts +0 -3
  136. package/dist/node/framework/Hydration/rsc.js +0 -20
  137. package/dist/node/framework/middleware.d.ts +3 -4
  138. package/dist/node/framework/middleware.js +4 -4
  139. package/dist/node/framework/plugin.d.ts +2 -2
  140. package/dist/node/framework/plugin.js +3 -3
  141. package/dist/node/framework/plugins/vite-plugin-hydrogen-config.js +1 -1
  142. package/dist/node/framework/plugins/vite-plugin-hydrogen-middleware.d.ts +2 -2
  143. package/dist/node/framework/plugins/vite-plugin-hydrogen-middleware.js +58 -3
  144. package/dist/node/storefront-api-types.d.ts +60 -6
  145. package/dist/node/storefront-api-types.js +6 -2
  146. package/dist/node/types.d.ts +11 -4
  147. package/dist/node/utilities/apiRoutes.d.ts +4 -4
  148. package/dist/node/utilities/apiRoutes.js +29 -16
  149. package/dist/node/utilities/bot-ua.js +4 -0
  150. package/dist/node/utilities/findRoutePrefix.d.ts +1 -0
  151. package/dist/node/utilities/findRoutePrefix.js +21 -0
  152. package/dist/node/utilities/log/utils.js +1 -1
  153. package/dist/node/utilities/parse.d.ts +1 -0
  154. package/dist/node/utilities/parse.js +13 -0
  155. package/dist/node/utilities/parseMetafieldValue/parseMetafieldValue.js +2 -1
  156. package/dist/node/utilities/storefrontApi.js +1 -0
  157. package/dist/node/version.d.ts +1 -1
  158. package/dist/node/version.js +1 -1
  159. package/package.json +8 -6
  160. package/dist/esnext/foundation/Boomerang/Boomerang.client.d.ts +0 -9
  161. package/dist/esnext/foundation/Boomerang/Boomerang.client.js +0 -66
package/CHANGELOG.md CHANGED
@@ -1,5 +1,214 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.19.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#1053](https://github.com/Shopify/hydrogen/pull/1053) [`c407f304`](https://github.com/Shopify/hydrogen/commit/c407f304352e0b781fa8a729674153ee9b971977) Thanks [@blittle](https://github.com/blittle)! - The selected country is now persisted a part of the session. This means that the page can be refreshed and the country will still be selected. There are a few breaking changes:
8
+
9
+ 1. `useCountry()` hook now only returns the currently selected country. The `setCountry()` method has been removed.
10
+ 2. The `useCountry()` hook expects a `countryCode` and `countryName` to be a part of the user session.
11
+ 3. The example `/countries` API route has been updated to accept a `POST` request to update the selected country. The CountrySelector components need to be updated to use that route.
12
+
13
+ ```diff
14
+ // src/routes/countries.server.jsx
15
+
16
+ -export async function api(request, {queryShop}) {
17
+ +export async function api(request, {queryShop, session}) {
18
+ + if (request.method === 'POST') {
19
+ + const {isoCode, name} = await request.json();
20
+ +
21
+ + await session.set('countryCode', isoCode);
22
+ + await session.set('countryName', name);
23
+ +
24
+ + return 'success';
25
+ + }
26
+
27
+ const {
28
+ data: {
29
+ localization: {availableCountries},
30
+ },
31
+ } = await queryShop({
32
+ query: QUERY,
33
+ });
34
+ return availableCountries.sort((a, b) => a.name.localeCompare(b.name));
35
+ }
36
+ ```
37
+
38
+ ```diff
39
+ // src/components/CountrySelector.client.jsx
40
+
41
+ export default function CountrySelector() {
42
+ const [listboxOpen, setListboxOpen] = useState(false);
43
+
44
+ - const [selectedCountry, setSelectedCountry] = useCountry();
45
+ + const [selectedCountry] = useCountry();
46
+
47
+ + const setSelectedCountry = useCallback(
48
+ + ({isoCode, name}) => {
49
+ + fetch(`/countries`, {
50
+ + body: JSON.stringify({isoCode, name}),
51
+ + method: 'POST',
52
+ + })
53
+ + .then(() => {
54
+ + window.location.reload();
55
+ + })
56
+ + .catch((error) => {
57
+ + console.error(error);
58
+ + });
59
+ + },
60
+ + [],
61
+ + );
62
+
63
+ return (
64
+ ...
65
+ );
66
+ }
67
+ ```
68
+
69
+ 4. Each server component page that depends on the selected country pulls it from the session with `useSession()`, rather than `serverProps`.
70
+
71
+ ```diff
72
+ // src/routes/products/[handle].server.jsx
73
+ + import { useSession } from '@shopify/hydrogen';
74
+
75
+ - export default function Product({country = {isoCode: 'US'}}) {
76
+ + export default function Product() {
77
+ const {handle} = useRouteParams();
78
+ + const {countryCode = 'US'} = useSession();
79
+ ...
80
+ }
81
+ ```
82
+
83
+ ### Patch Changes
84
+
85
+ - [#1264](https://github.com/Shopify/hydrogen/pull/1264) [`dc966e86`](https://github.com/Shopify/hydrogen/commit/dc966e86b35ffc8a41d8d62e129884926b8db8bc) Thanks [@arlyxiao](https://github.com/arlyxiao)! - Add more bots into user agents
86
+
87
+ * [#1245](https://github.com/Shopify/hydrogen/pull/1245) [`07866e82`](https://github.com/Shopify/hydrogen/commit/07866e8277dfa3195ef1896b16a58df495a9155f) Thanks [@0x15f](https://github.com/0x15f)! - [#1245](https://github.com/Shopify/hydrogen/pull/1245) - Support optional `priority` prop on Image component. When `true`, the image will be eagerly loaded. Defaults to `false`.
88
+
89
+ - [#1272](https://github.com/Shopify/hydrogen/pull/1272) [`c1888652`](https://github.com/Shopify/hydrogen/commit/c188865255c5f20d9db285e375c57127030e23e6) Thanks [@wizardlyhel](https://github.com/wizardlyhel)! - Remove flight chunk
90
+
91
+ ## 0.18.0
92
+
93
+ ### Minor Changes
94
+
95
+ - [#1065](https://github.com/Shopify/hydrogen/pull/1065) [`81ae47fd`](https://github.com/Shopify/hydrogen/commit/81ae47fdb01be06af155a61e574d43c73122c414) Thanks [@frandiox](https://github.com/frandiox)! - A new config file `hydrogen.config.js` replaces the existing `shopify.config.js` in your Hydrogen app.
96
+
97
+ ## Introducing `hydrogen.config.js`
98
+
99
+ Hydrogen apps now expect a `hydrogen.config.js` in the root folder. This config file accepts Shopify storefront credentials, routes, session configuration, and more.
100
+
101
+ To migrate existing apps, you should create a `hydrogen.config.js` (or `hydrogen.config.ts`) file in your Hydrogen app:
102
+
103
+ ```js
104
+ import {defineConfig} from '@shopify/hydrogen/config';
105
+ import {
106
+ CookieSessionStorage,
107
+ PerformanceMetricsServerAnalyticsConnector,
108
+ } from '@shopify/hydrogen';
109
+
110
+ export default defineConfig({
111
+ routes: import.meta.globEager('./src/routes/**/*.server.[jt](s|sx)'),
112
+ shopify: {
113
+ storeDomain: 'YOUR_STORE.myshopify.com',
114
+ storefrontToken: 'YOUR_STOREFRONT_TOKEN',
115
+ storefrontApiVersion: '2022-07',
116
+ },
117
+ session: CookieSessionStorage('__session', {
118
+ path: '/',
119
+ httpOnly: true,
120
+ secure: process.env.NODE_ENV === 'production',
121
+ sameSite: 'strict',
122
+ maxAge: 60 * 60 * 24 * 30,
123
+ }),
124
+ serverAnalyticsConnectors: [PerformanceMetricsServerAnalyticsConnector],
125
+ });
126
+ ```
127
+
128
+ Then, update your `App.server.jsx` to remove previous arguments from `renderHydrogen()`:
129
+
130
+ ```diff
131
+ import renderHydrogen from '@shopify/hydrogen/entry-server';
132
+
133
+ -function App({routes}) {
134
+ +function App() {
135
+ return (
136
+ <Suspense fallback={<LoadingFallback />}>
137
+ - <ShopifyProvider shopifyConfig={shopifyConfig}>
138
+ + <ShopifyProvider>
139
+ <CartProvider>
140
+ <DefaultSeo />
141
+ <Router>
142
+ - <FileRoutes routes={routes} />
143
+ + <FileRoutes />
144
+ <Route path="*" page={<NotFound />} />
145
+ </Router>
146
+ </CartProvider>
147
+ <PerformanceMetrics />
148
+ {process.env.LOCAL_DEV && <PerformanceMetricsDebug />}
149
+ </ShopifyProvider>
150
+ </Suspense>
151
+ );
152
+ }
153
+
154
+ -const routes = import.meta.globEager('./routes/**/*.server.[jt](s|sx)');
155
+ -
156
+ -export default renderHydrogen(App, {
157
+ - routes,
158
+ - shopifyConfig,
159
+ - session: CookieSessionStorage('__session', {
160
+ - path: '/',
161
+ - httpOnly: true,
162
+ - secure: process.env.NODE_ENV === 'production',
163
+ - sameSite: 'strict',
164
+ - maxAge: 60 * 60 * 24 * 30,
165
+ - }),
166
+ - serverAnalyticsConnectors: [PerformanceMetricsServerAnalyticsConnector],
167
+ -});
168
+ +export default renderHydrogen(App);
169
+ ```
170
+
171
+ Next, update `vite.config.js` in your app to remove references to `shopifyConfig`:
172
+
173
+ ```diff
174
+ import {defineConfig} from 'vite';
175
+ import hydrogen from '@shopify/hydrogen/plugin';
176
+ -import shopifyConfig from './shopify.config';
177
+
178
+ // https://vitejs.dev/config/
179
+ export default defineConfig({
180
+ - plugins: [hydrogen(shopifyConfig)],
181
+ + plugins: [hydrogen()],
182
+ ```
183
+
184
+ Finally, delete `shopify.config.js` from your app.
185
+
186
+ [Read more about the `hydrogen.config.js` file](https://shopify.dev/custom-storefronts/hydrogen/framework/hydrogen-config)
187
+
188
+ * [#1214](https://github.com/Shopify/hydrogen/pull/1214) [`58ef6d69`](https://github.com/Shopify/hydrogen/commit/58ef6d69f1148e7bc8452fa77e7e8f54396c6105) Thanks [@frehner](https://github.com/frehner)! - Upgraded SFAPI version to 2022-07
189
+
190
+ - [#1232](https://github.com/Shopify/hydrogen/pull/1232) [`d3956d62`](https://github.com/Shopify/hydrogen/commit/d3956d623adb86371ab214b102b53c62ea9ce26c) Thanks [@arlyxiao](https://github.com/arlyxiao)! - Upgrade body-parser in hydrogen package
191
+
192
+ ### Patch Changes
193
+
194
+ - [#1211](https://github.com/Shopify/hydrogen/pull/1211) [`f3d26511`](https://github.com/Shopify/hydrogen/commit/f3d26511b1b0b94de1a43f76a0be9d99b5f2a8f7) Thanks [@wizardlyhel](https://github.com/wizardlyhel)! - Build chunks are inside assets folder
195
+
196
+ * [#1215](https://github.com/Shopify/hydrogen/pull/1215) [`a0ed7c06`](https://github.com/Shopify/hydrogen/commit/a0ed7c06d045a0063a356097dafcc25e5361aad1) Thanks [@frehner](https://github.com/frehner)! - `useMoney` now returns two additional properties: `withoutTrailingZeros` and `withoutTrailingZerosAndCurrency`
197
+
198
+ `<Money />` now has two additional and optional props: `withoutMoney` and `withoutCurrency`.
199
+
200
+ - [#1242](https://github.com/Shopify/hydrogen/pull/1242) [`c277c688`](https://github.com/Shopify/hydrogen/commit/c277c68836d6d75d509cc68c74e3ccd33706a0c7) Thanks [@blittle](https://github.com/blittle)! - Prevent JSON parsing from prototype poisoning vulnerabilities
201
+
202
+ * [#1210](https://github.com/Shopify/hydrogen/pull/1210) [`a844d26e`](https://github.com/Shopify/hydrogen/commit/a844d26ef258c28fded5293054389b719f0b86f4) Thanks [@blittle](https://github.com/blittle)! - Add eslint back and fix stale product options
203
+
204
+ ## 0.17.3
205
+
206
+ ### Patch Changes
207
+
208
+ - [#1096](https://github.com/Shopify/hydrogen/pull/1096) [`0a15376e`](https://github.com/Shopify/hydrogen/commit/0a15376ec806054ddd5848d9dbfa6e50a85beb49) Thanks [@wizardlyhel](https://github.com/wizardlyhel)! - Make performance data available with ClientAnalytics and optional for developers to include
209
+
210
+ * [#1209](https://github.com/Shopify/hydrogen/pull/1209) [`d0dada0a`](https://github.com/Shopify/hydrogen/commit/d0dada0a0b3170d2cb885d2f29bbbef0c6d9e9e4) Thanks [@blittle](https://github.com/blittle)! - Make metafields optional within the ProductProvider. Fixes #1127
211
+
3
212
  ## 0.17.2
4
213
 
5
214
  ### Patch Changes
package/config.js ADDED
@@ -0,0 +1 @@
1
+ export * from './dist/esnext/config';
@@ -11,3 +11,5 @@ export { useRouteParams } from './foundation/useRouteParams/useRouteParams';
11
11
  export { useNavigate } from './foundation/useNavigate/useNavigate';
12
12
  export { fetchSync } from './foundation/fetchSync/client/fetchSync';
13
13
  export { suspendFunction, preloadFunction } from './utilities/suspense';
14
+ export { PerformanceMetrics } from './foundation/Analytics/connectors/PerformanceMetrics/PerformanceMetrics.client';
15
+ export { PerformanceMetricsDebug } from './foundation/Analytics/connectors/PerformanceMetrics/PerformanceMetricsDebug.client';
@@ -11,3 +11,5 @@ export { useRouteParams } from './foundation/useRouteParams/useRouteParams';
11
11
  export { useNavigate } from './foundation/useNavigate/useNavigate';
12
12
  export { fetchSync } from './foundation/fetchSync/client/fetchSync';
13
13
  export { suspendFunction, preloadFunction } from './utilities/suspense';
14
+ export { PerformanceMetrics } from './foundation/Analytics/connectors/PerformanceMetrics/PerformanceMetrics.client';
15
+ export { PerformanceMetricsDebug } from './foundation/Analytics/connectors/PerformanceMetrics/PerformanceMetricsDebug.client';
@@ -27,9 +27,9 @@ export function AddToCartButton(props) {
27
27
  setAddingItem(true);
28
28
  linesAdd([
29
29
  {
30
- quantity: quantity,
30
+ quantity,
31
31
  merchandiseId: variantId,
32
- attributes: attributes,
32
+ attributes,
33
33
  },
34
34
  ]);
35
35
  } }, children),
@@ -1,7 +1,7 @@
1
1
  import React, { useEffect, useCallback, useReducer, useMemo, useRef, } from 'react';
2
2
  import { flattenConnection } from '../../utilities';
3
3
  import { CartLineAdd, CartCreate, CartLineRemove, CartLineUpdate, CartNoteUpdate, CartBuyerIdentityUpdate, CartAttributesUpdate, CartDiscountCodesUpdate, CartQuery, } from './cart-queries';
4
- import { useCartFetch } from './hooks';
4
+ import { useCartFetch } from './hooks.client';
5
5
  import { CartContext } from './context';
6
6
  import { CART_ID_STORAGE_KEY } from './constants';
7
7
  import { useServerProps } from '../../foundation/useServerProps';
@@ -197,7 +197,7 @@ export function CartProvider({ children, numCartLines, onCreate, onLineAdd, onLi
197
197
  if (error) {
198
198
  dispatch({
199
199
  type: 'reject',
200
- error: error,
200
+ error,
201
201
  });
202
202
  }
203
203
  if ((_b = data === null || data === void 0 ? void 0 : data.cartCreate) === null || _b === void 0 ? void 0 : _b.cart) {
@@ -223,7 +223,7 @@ export function CartProvider({ children, numCartLines, onCreate, onLineAdd, onLi
223
223
  query: CartLineAdd,
224
224
  variables: {
225
225
  cartId: state.cart.id,
226
- lines: lines,
226
+ lines,
227
227
  numCartLines,
228
228
  country: countryCode,
229
229
  },
@@ -231,7 +231,7 @@ export function CartProvider({ children, numCartLines, onCreate, onLineAdd, onLi
231
231
  if (error) {
232
232
  dispatch({
233
233
  type: 'reject',
234
- error: error,
234
+ error,
235
235
  });
236
236
  }
237
237
  if ((_a = data === null || data === void 0 ? void 0 : data.cartLinesAdd) === null || _a === void 0 ? void 0 : _a.cart) {
@@ -255,7 +255,7 @@ export function CartProvider({ children, numCartLines, onCreate, onLineAdd, onLi
255
255
  query: CartLineRemove,
256
256
  variables: {
257
257
  cartId: state.cart.id,
258
- lines: lines,
258
+ lines,
259
259
  numCartLines,
260
260
  country: countryCode,
261
261
  },
@@ -287,7 +287,7 @@ export function CartProvider({ children, numCartLines, onCreate, onLineAdd, onLi
287
287
  query: CartLineUpdate,
288
288
  variables: {
289
289
  cartId: state.cart.id,
290
- lines: lines,
290
+ lines,
291
291
  numCartLines,
292
292
  country: countryCode,
293
293
  },
@@ -295,7 +295,7 @@ export function CartProvider({ children, numCartLines, onCreate, onLineAdd, onLi
295
295
  if (error) {
296
296
  dispatch({
297
297
  type: 'reject',
298
- error: error,
298
+ error,
299
299
  });
300
300
  }
301
301
  if ((_a = data === null || data === void 0 ? void 0 : data.cartLinesUpdate) === null || _a === void 0 ? void 0 : _a.cart) {
@@ -319,7 +319,7 @@ export function CartProvider({ children, numCartLines, onCreate, onLineAdd, onLi
319
319
  query: CartNoteUpdate,
320
320
  variables: {
321
321
  cartId: state.cart.id,
322
- note: note,
322
+ note,
323
323
  numCartLines,
324
324
  country: countryCode,
325
325
  },
@@ -327,7 +327,7 @@ export function CartProvider({ children, numCartLines, onCreate, onLineAdd, onLi
327
327
  if (error) {
328
328
  dispatch({
329
329
  type: 'reject',
330
- error: error,
330
+ error,
331
331
  });
332
332
  }
333
333
  if ((_a = data === null || data === void 0 ? void 0 : data.cartNoteUpdate) === null || _a === void 0 ? void 0 : _a.cart) {
@@ -355,7 +355,7 @@ export function CartProvider({ children, numCartLines, onCreate, onLineAdd, onLi
355
355
  if (error) {
356
356
  dispatch({
357
357
  type: 'reject',
358
- error: error,
358
+ error,
359
359
  });
360
360
  }
361
361
  if ((_a = data === null || data === void 0 ? void 0 : data.cartBuyerIdentityUpdate) === null || _a === void 0 ? void 0 : _a.cart) {
@@ -375,7 +375,7 @@ export function CartProvider({ children, numCartLines, onCreate, onLineAdd, onLi
375
375
  query: CartAttributesUpdate,
376
376
  variables: {
377
377
  cartId: state.cart.id,
378
- attributes: attributes,
378
+ attributes,
379
379
  numCartLines,
380
380
  country: countryCode,
381
381
  },
@@ -383,7 +383,7 @@ export function CartProvider({ children, numCartLines, onCreate, onLineAdd, onLi
383
383
  if (error) {
384
384
  dispatch({
385
385
  type: 'reject',
386
- error: error,
386
+ error,
387
387
  });
388
388
  }
389
389
  if ((_a = data === null || data === void 0 ? void 0 : data.cartAttributesUpdate) === null || _a === void 0 ? void 0 : _a.cart) {
@@ -403,7 +403,7 @@ export function CartProvider({ children, numCartLines, onCreate, onLineAdd, onLi
403
403
  query: CartDiscountCodesUpdate,
404
404
  variables: {
405
405
  cartId: state.cart.id,
406
- discountCodes: discountCodes,
406
+ discountCodes,
407
407
  numCartLines,
408
408
  country: countryCode,
409
409
  },
@@ -411,7 +411,7 @@ export function CartProvider({ children, numCartLines, onCreate, onLineAdd, onLi
411
411
  if (error) {
412
412
  dispatch({
413
413
  type: 'reject',
414
- error: error,
414
+ error,
415
415
  });
416
416
  }
417
417
  if ((_a = data === null || data === void 0 ? void 0 : data.cartDiscountCodesUpdate) === null || _a === void 0 ? void 0 : _a.cart) {
@@ -440,6 +440,7 @@ export function CartProvider({ children, numCartLines, onCreate, onLineAdd, onLi
440
440
  return;
441
441
  }
442
442
  buyerIdentityUpdate({ countryCode }, state);
443
+ // eslint-disable-next-line react-hooks/exhaustive-deps
443
444
  }, [countryCode]);
444
445
  const cartContextValue = useMemo(() => {
445
446
  return {
@@ -1,4 +1,4 @@
1
1
  export { CartProvider } from './CartProvider.client';
2
- export { useCartFetch, useInstantCheckout } from './hooks';
2
+ export { useCartFetch, useInstantCheckout } from './hooks.client';
3
3
  export { useCart } from '../../hooks/useCart';
4
4
  export type { State, Status, Cart, CartWithActions, CartAction } from './types';
@@ -1,3 +1,3 @@
1
1
  export { CartProvider } from './CartProvider.client';
2
- export { useCartFetch, useInstantCheckout } from './hooks';
2
+ export { useCartFetch, useInstantCheckout } from './hooks.client';
3
3
  export { useCart } from '../../hooks/useCart';
@@ -19,9 +19,9 @@ export default function DevTools() {
19
19
  const entry = perfData[0];
20
20
  let activePanelContent = null;
21
21
  switch (activePanel) {
22
- case 'warnings':
22
+ case 'warnings': {
23
23
  const warningsMarkup = warnings
24
- ? warnings.map((war, i) => React.createElement("li", { key: war + i }, war))
24
+ ? warnings.map((war, i) => React.createElement("li", { key: war + i }, war)) // eslint-disable-line react/no-array-index-key
25
25
  : null;
26
26
  activePanelContent = (React.createElement(React.Fragment, null,
27
27
  React.createElement(PanelHeading, null, "Overfetched graphQL fields"),
@@ -31,6 +31,7 @@ export default function DevTools() {
31
31
  fontSize: '0.9em',
32
32
  } }, warningsMarkup)));
33
33
  break;
34
+ }
34
35
  case 'network':
35
36
  activePanelContent = (React.createElement(React.Fragment, null,
36
37
  React.createElement(PanelHeading, null, "Metrics"),
@@ -11,6 +11,12 @@ export interface BaseImageProps {
11
11
  * then the value can be a property of the `loaderOptions` object (for example, `{scale: 2}`).
12
12
  */
13
13
  loaderOptions?: ImageLoaderOptions['options'];
14
+ /**
15
+ * Whether the image will be immediately loaded. Defaults to `false`. This prop should be used only when
16
+ * the image is visible above the fold. For more information, refer to the
17
+ * [Image Embed element's loading attribute](https://developer.mozilla.org/enUS/docs/Web/HTML/Element/img#attr-loading).
18
+ */
19
+ priority?: boolean;
14
20
  }
15
21
  interface MediaImagePropsBase extends BaseImageProps {
16
22
  /** An object with fields that correspond to the Storefront API's
@@ -6,7 +6,7 @@ import { shopifyImageLoader, getShopifyImageDimensions, } from '../../utilities'
6
6
  */
7
7
  export function Image(props) {
8
8
  var _a, _b, _c, _d;
9
- const { data, options, src, id, alt, width, height, loader, loaderOptions, ...passthroughProps } = props;
9
+ const { data, options, src, id, alt, width, height, loader, loaderOptions, priority, ...passthroughProps } = props;
10
10
  if (!data && !src) {
11
11
  throw new Error('Image component: requires either an `data` or `src` prop.');
12
12
  }
@@ -21,6 +21,7 @@ export function Image(props) {
21
21
  loaderOptions,
22
22
  id,
23
23
  alt,
24
+ priority,
24
25
  })
25
26
  : {
26
27
  src,
@@ -29,14 +30,17 @@ export function Image(props) {
29
30
  width,
30
31
  height,
31
32
  loader,
33
+ priority,
32
34
  loaderOptions: { width, height, ...loaderOptions },
33
35
  };
34
36
  const srcPath = imgProps.loader
35
37
  ? imgProps.loader({ src: imgProps.src, options: imgProps.loaderOptions })
36
38
  : imgProps.src;
37
- return (React.createElement("img", { id: (_a = imgProps.id) !== null && _a !== void 0 ? _a : '', loading: "lazy", alt: (_b = imgProps.alt) !== null && _b !== void 0 ? _b : '', ...passthroughProps, src: srcPath, width: (_c = imgProps.width) !== null && _c !== void 0 ? _c : undefined, height: (_d = imgProps.height) !== null && _d !== void 0 ? _d : undefined }));
39
+ /* eslint-disable hydrogen/prefer-image-component */
40
+ return (React.createElement("img", { id: (_a = imgProps.id) !== null && _a !== void 0 ? _a : '', loading: imgProps.priority ? 'eager' : 'lazy', alt: (_b = imgProps.alt) !== null && _b !== void 0 ? _b : '', ...passthroughProps, src: srcPath, width: (_c = imgProps.width) !== null && _c !== void 0 ? _c : undefined, height: (_d = imgProps.height) !== null && _d !== void 0 ? _d : undefined }));
41
+ /* eslint-enable hydrogen/prefer-image-component */
38
42
  }
39
- function convertShopifyImageData({ data, options, loader, loaderOptions, id: propId, alt, }) {
43
+ function convertShopifyImageData({ data, options, loader, priority, loaderOptions, id: propId, alt, }) {
40
44
  const { url: src, altText, id } = data;
41
45
  if (!src) {
42
46
  throw new Error(`<Image/> requires 'data.url' when using the 'data' prop`);
@@ -50,5 +54,6 @@ function convertShopifyImageData({ data, options, loader, loaderOptions, id: pro
50
54
  height,
51
55
  loader: loader ? loader : shopifyImageLoader,
52
56
  loaderOptions: { ...options, ...loaderOptions },
57
+ priority,
53
58
  };
54
59
  }
@@ -30,12 +30,21 @@ export const Link = React.forwardRef(function Link(props, ref) {
30
30
  e.preventDefault();
31
31
  // If the URL hasn't changed, the regular <a> will do a replace
32
32
  const replace = !!_replace || createPath(location) === createPath({ pathname: to });
33
- navigate(props.to, {
33
+ navigate(to, {
34
34
  replace,
35
35
  clientState,
36
36
  });
37
37
  }
38
- }, [reloadDocument, target, _replace, to, clientState, onClick, location]);
38
+ }, [
39
+ reloadDocument,
40
+ target,
41
+ _replace,
42
+ to,
43
+ clientState,
44
+ onClick,
45
+ location,
46
+ navigate,
47
+ ]);
39
48
  const signalPrefetchIntent = () => {
40
49
  /**
41
50
  * startTransition to yield to more important updates
@@ -1,18 +1,5 @@
1
- import React, { useMemo, useState, useCallback } from 'react';
1
+ import React from 'react';
2
2
  import { LocalizationContext } from './LocalizationContext.client';
3
- import { useServerProps } from '../../foundation/useServerProps';
4
3
  export default function LocalizationClientProvider({ localization, children, }) {
5
- const { setServerProps } = useServerProps();
6
- const [country, setCountry] = useState(localization.country);
7
- const setter = useCallback((country) => {
8
- setCountry(country);
9
- setServerProps('country', country);
10
- }, [setServerProps]);
11
- const contextValue = useMemo(() => {
12
- return {
13
- country,
14
- setCountry: setter,
15
- };
16
- }, [country, setter]);
17
- return (React.createElement(LocalizationContext.Provider, { value: contextValue }, children));
4
+ return (React.createElement(LocalizationContext.Provider, { value: localization }, children));
18
5
  }
@@ -2,6 +2,5 @@ import type { LocalizationQuery } from './LocalizationProvider.server';
2
2
  export declare type Localization = LocalizationQuery['localization'];
3
3
  export interface LocalizationContextValue {
4
4
  country?: Localization['country'];
5
- setCountry(country: Localization['country']): void;
6
5
  }
7
6
  export declare const LocalizationContext: import("react").Context<LocalizationContextValue | null>;
@@ -1,6 +1,6 @@
1
1
  import { ReactNode } from 'react';
2
2
  import { PreloadOptions } from '../../types';
3
- import { Country, Currency } from '../../storefront-api-types';
3
+ import { Country } from '../../storefront-api-types';
4
4
  export interface LocalizationProviderProps {
5
5
  /** A `ReactNode` element. */
6
6
  children: ReactNode;
@@ -28,10 +28,6 @@ export declare type LocalizationQuery = {
28
28
  } & {
29
29
  country: {
30
30
  __typename?: 'Country';
31
- } & Pick<Country, 'isoCode' | 'name'> & {
32
- currency: {
33
- __typename?: 'Currency';
34
- } & Pick<Currency, 'isoCode'>;
35
- };
31
+ } & Pick<Country, 'isoCode' | 'name'>;
36
32
  };
37
33
  };
@@ -3,6 +3,7 @@ import LocalizationClientProvider from './LocalizationClientProvider.client';
3
3
  import { useShop } from '../../foundation/useShop';
4
4
  import { useShopQuery } from '../../hooks/useShopQuery';
5
5
  import { CacheDays } from '../../framework/CachingStrategy';
6
+ import { useSession } from '../../foundation/useSession/useSession';
6
7
  /**
7
8
  * The `LocalizationProvider` component automatically queries the Storefront API's
8
9
  * [`localization`](https://shopify.dev/api/storefront/reference/common-objects/queryroot) field
@@ -14,13 +15,21 @@ import { CacheDays } from '../../framework/CachingStrategy';
14
15
  */
15
16
  export function LocalizationProvider(props) {
16
17
  const { languageCode } = useShop();
18
+ const { countryCode, countryName } = useSession();
17
19
  const { data: { localization }, } = useShopQuery({
18
- query: query,
20
+ query,
19
21
  variables: { language: languageCode },
20
22
  cache: CacheDays(),
21
23
  preload: props.preload,
22
24
  });
23
- return (React.createElement(LocalizationClientProvider, { localization: localization }, props.children));
25
+ return (React.createElement(LocalizationClientProvider, { localization: countryCode
26
+ ? {
27
+ country: {
28
+ name: countryName,
29
+ isoCode: countryCode,
30
+ },
31
+ }
32
+ : localization }, props.children));
24
33
  }
25
34
  const query = `
26
35
  query Localization($language: LanguageCode)
@@ -29,9 +38,6 @@ query Localization($language: LanguageCode)
29
38
  country {
30
39
  isoCode
31
40
  name
32
- currency {
33
- isoCode
34
- }
35
41
  }
36
42
  }
37
43
  }
@@ -52,18 +52,17 @@ export function Metafield(props) {
52
52
  }
53
53
  case 'url':
54
54
  return (React.createElement("a", { href: data.value, ...passthroughProps }, data.value));
55
- case 'json':
55
+ case 'json': {
56
56
  const Wrapper = as !== null && as !== void 0 ? as : 'span';
57
57
  return (React.createElement(Wrapper, { ...passthroughProps }, JSON.stringify(data.value)));
58
+ }
58
59
  case 'file_reference': {
59
60
  if (((_a = data.reference) === null || _a === void 0 ? void 0 : _a.__typename) === 'MediaImage') {
60
61
  const ref = data.reference;
61
62
  return ref.image ? (React.createElement(Image, { data: ref.image, ...passthroughProps })) : null;
62
63
  }
63
64
  }
64
- default: {
65
- const Wrapper = as !== null && as !== void 0 ? as : 'span';
66
- return React.createElement(Wrapper, { ...passthroughProps }, data.value.toString());
67
- }
68
65
  }
66
+ const Wrapper = as !== null && as !== void 0 ? as : 'span';
67
+ return React.createElement(Wrapper, { ...passthroughProps }, data.value.toString());
69
68
  }
@@ -1,5 +1,5 @@
1
1
  import React, { useState, useEffect, useCallback, } from 'react';
2
- import { useLoadScript } from '../../hooks/useLoadScript/useLoadScript';
2
+ import { useLoadScript } from '../../hooks/useLoadScript/useLoadScript.client';
3
3
  /**
4
4
  * The `ModelViewer` component renders a 3D model (with the `model-viewer` tag) for
5
5
  * the Storefront API's [Model3d object](https://shopify.dev/api/storefront/reference/products/model3d).
@@ -5,11 +5,15 @@ interface MoneyProps<TTag> {
5
5
  as?: TTag;
6
6
  /** An object with fields that correspond to the Storefront API's [MoneyV2 object](https://shopify.dev/api/storefront/reference/common-objects/moneyv2). */
7
7
  data: PartialDeep<MoneyV2>;
8
+ /** Whether to remove the currency symbol from the output. */
9
+ withoutCurrency?: boolean;
10
+ /** Whether to remove trailing zeros (fractional money) from the output. */
11
+ withoutTrailingZeros?: boolean;
8
12
  }
9
13
  /**
10
14
  * The `Money` component renders a string of the Storefront API's
11
15
  * [MoneyV2 object](https://shopify.dev/api/storefront/reference/common-objects/moneyv2) according to the
12
- * `defaultLocale` in the `shopify.config.js` file.
16
+ * `defaultLocale` in [the `hydrogen.config.js` file](https://shopify.dev/custom-storefronts/hydrogen/framework/hydrogen-config).
13
17
  */
14
18
  export declare function Money<TTag extends keyof JSX.IntrinsicElements = 'div'>(props: JSX.IntrinsicElements[TTag] & MoneyProps<TTag>): JSX.Element;
15
19
  export {};