@ohos-ports/shopify 4.8.0-beta.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 (606) hide show
  1. package/README.md +75 -0
  2. package/bin/run.cmd +3 -0
  3. package/bin/run.js +11 -0
  4. package/dist/acorn-7M27BPGP.js +16 -0
  5. package/dist/analytics-3IIUBZ3B.js +1 -0
  6. package/dist/analytics-OOT5AB52.js +1 -0
  7. package/dist/angular-DW5TQVCM.js +4 -0
  8. package/dist/assets/graphiql/favicon.ico +0 -0
  9. package/dist/assets/graphiql/style.css +58 -0
  10. package/dist/assets/hydrogen/bundle/analyzer.html +2056 -0
  11. package/dist/assets/hydrogen/i18n/domains.ts +21 -0
  12. package/dist/assets/hydrogen/i18n/mock-i18n-types.ts +5 -0
  13. package/dist/assets/hydrogen/i18n/subdomains.ts +20 -0
  14. package/dist/assets/hydrogen/i18n/subfolders.ts +22 -0
  15. package/dist/assets/hydrogen/routes/locale-check.ts +16 -0
  16. package/dist/assets/hydrogen/starter/.cursor/rules/hydrogen-react-router.mdc +52 -0
  17. package/dist/assets/hydrogen/starter/.graphqlrc.ts +29 -0
  18. package/dist/assets/hydrogen/starter/AGENTS.md +5 -0
  19. package/dist/assets/hydrogen/starter/CHANGELOG.md +2839 -0
  20. package/dist/assets/hydrogen/starter/CLAUDE.md +1 -0
  21. package/dist/assets/hydrogen/starter/README.md +45 -0
  22. package/dist/assets/hydrogen/starter/app/assets/favicon.svg +28 -0
  23. package/dist/assets/hydrogen/starter/app/components/AddToCartButton.tsx +37 -0
  24. package/dist/assets/hydrogen/starter/app/components/Aside.tsx +101 -0
  25. package/dist/assets/hydrogen/starter/app/components/CartLineItem.tsx +197 -0
  26. package/dist/assets/hydrogen/starter/app/components/CartMain.tsx +109 -0
  27. package/dist/assets/hydrogen/starter/app/components/CartSummary.tsx +300 -0
  28. package/dist/assets/hydrogen/starter/app/components/Footer.tsx +129 -0
  29. package/dist/assets/hydrogen/starter/app/components/Header.tsx +231 -0
  30. package/dist/assets/hydrogen/starter/app/components/MockShopNotice.tsx +20 -0
  31. package/dist/assets/hydrogen/starter/app/components/PageLayout.tsx +174 -0
  32. package/dist/assets/hydrogen/starter/app/components/PaginatedResourceSection.tsx +61 -0
  33. package/dist/assets/hydrogen/starter/app/components/ProductForm.tsx +150 -0
  34. package/dist/assets/hydrogen/starter/app/components/ProductImage.tsx +23 -0
  35. package/dist/assets/hydrogen/starter/app/components/ProductItem.tsx +44 -0
  36. package/dist/assets/hydrogen/starter/app/components/ProductPrice.tsx +27 -0
  37. package/dist/assets/hydrogen/starter/app/components/SearchForm.tsx +68 -0
  38. package/dist/assets/hydrogen/starter/app/components/SearchFormPredictive.tsx +76 -0
  39. package/dist/assets/hydrogen/starter/app/components/SearchResults.tsx +161 -0
  40. package/dist/assets/hydrogen/starter/app/components/SearchResultsPredictive.tsx +304 -0
  41. package/dist/assets/hydrogen/starter/app/entry.client.tsx +21 -0
  42. package/dist/assets/hydrogen/starter/app/entry.server.tsx +53 -0
  43. package/dist/assets/hydrogen/starter/app/graphql/customer-account/CustomerAddressMutations.ts +64 -0
  44. package/dist/assets/hydrogen/starter/app/graphql/customer-account/CustomerDetailsQuery.ts +40 -0
  45. package/dist/assets/hydrogen/starter/app/graphql/customer-account/CustomerOrderQuery.ts +90 -0
  46. package/dist/assets/hydrogen/starter/app/graphql/customer-account/CustomerOrdersQuery.ts +63 -0
  47. package/dist/assets/hydrogen/starter/app/graphql/customer-account/CustomerUpdateMutation.ts +25 -0
  48. package/dist/assets/hydrogen/starter/app/lib/context.ts +65 -0
  49. package/dist/assets/hydrogen/starter/app/lib/fragments.ts +242 -0
  50. package/dist/assets/hydrogen/starter/app/lib/orderFilters.ts +90 -0
  51. package/dist/assets/hydrogen/starter/app/lib/redirect.ts +23 -0
  52. package/dist/assets/hydrogen/starter/app/lib/search.ts +79 -0
  53. package/dist/assets/hydrogen/starter/app/lib/session.ts +72 -0
  54. package/dist/assets/hydrogen/starter/app/lib/variants.ts +46 -0
  55. package/dist/assets/hydrogen/starter/app/root.tsx +209 -0
  56. package/dist/assets/hydrogen/starter/app/routes/$.tsx +11 -0
  57. package/dist/assets/hydrogen/starter/app/routes/[robots.txt].tsx +78 -0
  58. package/dist/assets/hydrogen/starter/app/routes/[sitemap.xml].tsx +16 -0
  59. package/dist/assets/hydrogen/starter/app/routes/_index.tsx +177 -0
  60. package/dist/assets/hydrogen/starter/app/routes/account.$.tsx +9 -0
  61. package/dist/assets/hydrogen/starter/app/routes/account._index.tsx +5 -0
  62. package/dist/assets/hydrogen/starter/app/routes/account.addresses.tsx +516 -0
  63. package/dist/assets/hydrogen/starter/app/routes/account.orders.$id.tsx +222 -0
  64. package/dist/assets/hydrogen/starter/app/routes/account.orders._index.tsx +222 -0
  65. package/dist/assets/hydrogen/starter/app/routes/account.profile.tsx +133 -0
  66. package/dist/assets/hydrogen/starter/app/routes/account.tsx +97 -0
  67. package/dist/assets/hydrogen/starter/app/routes/account_.authorize.tsx +5 -0
  68. package/dist/assets/hydrogen/starter/app/routes/account_.login.tsx +17 -0
  69. package/dist/assets/hydrogen/starter/app/routes/account_.logout.tsx +11 -0
  70. package/dist/assets/hydrogen/starter/app/routes/blogs.$blogHandle.$articleHandle.tsx +129 -0
  71. package/dist/assets/hydrogen/starter/app/routes/blogs.$blogHandle._index.tsx +175 -0
  72. package/dist/assets/hydrogen/starter/app/routes/blogs._index.tsx +109 -0
  73. package/dist/assets/hydrogen/starter/app/routes/cart.$lines.tsx +70 -0
  74. package/dist/assets/hydrogen/starter/app/routes/cart.tsx +113 -0
  75. package/dist/assets/hydrogen/starter/app/routes/collections.$handle.tsx +161 -0
  76. package/dist/assets/hydrogen/starter/app/routes/collections._index.tsx +133 -0
  77. package/dist/assets/hydrogen/starter/app/routes/collections.all.tsx +122 -0
  78. package/dist/assets/hydrogen/starter/app/routes/discount.$code.tsx +48 -0
  79. package/dist/assets/hydrogen/starter/app/routes/pages.$handle.tsx +88 -0
  80. package/dist/assets/hydrogen/starter/app/routes/policies.$handle.tsx +93 -0
  81. package/dist/assets/hydrogen/starter/app/routes/policies._index.tsx +69 -0
  82. package/dist/assets/hydrogen/starter/app/routes/products.$handle.tsx +232 -0
  83. package/dist/assets/hydrogen/starter/app/routes/search.tsx +426 -0
  84. package/dist/assets/hydrogen/starter/app/routes/sitemap.$type.$page[.xml].tsx +23 -0
  85. package/dist/assets/hydrogen/starter/app/routes.ts +9 -0
  86. package/dist/assets/hydrogen/starter/app/styles/app.css +645 -0
  87. package/dist/assets/hydrogen/starter/app/styles/reset.css +139 -0
  88. package/dist/assets/hydrogen/starter/customer-accountapi.generated.d.ts +543 -0
  89. package/dist/assets/hydrogen/starter/env.d.ts +7 -0
  90. package/dist/assets/hydrogen/starter/eslint.config.js +247 -0
  91. package/dist/assets/hydrogen/starter/guides/predictiveSearch/predictiveSearch.jpg +0 -0
  92. package/dist/assets/hydrogen/starter/guides/predictiveSearch/predictiveSearch.md +394 -0
  93. package/dist/assets/hydrogen/starter/guides/search/search.jpg +0 -0
  94. package/dist/assets/hydrogen/starter/guides/search/search.md +335 -0
  95. package/dist/assets/hydrogen/starter/package.json +62 -0
  96. package/dist/assets/hydrogen/starter/public/.gitkeep +0 -0
  97. package/dist/assets/hydrogen/starter/react-router.config.ts +13 -0
  98. package/dist/assets/hydrogen/starter/server.ts +59 -0
  99. package/dist/assets/hydrogen/starter/storefrontapi.generated.d.ts +1342 -0
  100. package/dist/assets/hydrogen/starter/tsconfig.json +43 -0
  101. package/dist/assets/hydrogen/starter/vite.config.ts +44 -0
  102. package/dist/assets/hydrogen/tailwind/package.json +11 -0
  103. package/dist/assets/hydrogen/tailwind/tailwind.css +6 -0
  104. package/dist/assets/hydrogen/vanilla-extract/package.json +8 -0
  105. package/dist/assets/hydrogen/virtual-routes/assets/debug-network.css +609 -0
  106. package/dist/assets/hydrogen/virtual-routes/assets/favicon-dark.svg +20 -0
  107. package/dist/assets/hydrogen/virtual-routes/assets/favicon.svg +28 -0
  108. package/dist/assets/hydrogen/virtual-routes/assets/inter-variable-font.woff2 +0 -0
  109. package/dist/assets/hydrogen/virtual-routes/assets/jetbrainsmono-variable-font.woff2 +0 -0
  110. package/dist/assets/hydrogen/virtual-routes/assets/styles.css +249 -0
  111. package/dist/assets/hydrogen/virtual-routes/components/FlameChartWrapper.jsx +123 -0
  112. package/dist/assets/hydrogen/virtual-routes/components/HydrogenLogoBaseBW.jsx +32 -0
  113. package/dist/assets/hydrogen/virtual-routes/components/HydrogenLogoBaseColor.jsx +47 -0
  114. package/dist/assets/hydrogen/virtual-routes/components/IconBanner.jsx +292 -0
  115. package/dist/assets/hydrogen/virtual-routes/components/IconClose.jsx +38 -0
  116. package/dist/assets/hydrogen/virtual-routes/components/IconDiscard.jsx +44 -0
  117. package/dist/assets/hydrogen/virtual-routes/components/IconError.jsx +61 -0
  118. package/dist/assets/hydrogen/virtual-routes/components/IconGithub.jsx +23 -0
  119. package/dist/assets/hydrogen/virtual-routes/components/IconTwitter.jsx +21 -0
  120. package/dist/assets/hydrogen/virtual-routes/components/Layout.jsx +7 -0
  121. package/dist/assets/hydrogen/virtual-routes/components/RequestDetails.jsx +171 -0
  122. package/dist/assets/hydrogen/virtual-routes/components/RequestTable.jsx +91 -0
  123. package/dist/assets/hydrogen/virtual-routes/components/RequestWaterfall.jsx +151 -0
  124. package/dist/assets/hydrogen/virtual-routes/layout.jsx +33 -0
  125. package/dist/assets/hydrogen/virtual-routes/lib/useDebugNetworkServer.jsx +178 -0
  126. package/dist/assets/hydrogen/virtual-routes/routes/[.]well-known.appspecific.com[.]chrome[.]devtools[.]json.jsx +37 -0
  127. package/dist/assets/hydrogen/virtual-routes/routes/graphiql.jsx +5 -0
  128. package/dist/assets/hydrogen/virtual-routes/routes/index.jsx +265 -0
  129. package/dist/assets/hydrogen/virtual-routes/routes/subrequest-profiler.jsx +243 -0
  130. package/dist/assets/hydrogen/virtual-routes/virtual-root-with-layout.jsx +63 -0
  131. package/dist/assets/hydrogen/virtual-routes/virtual-root.jsx +67 -0
  132. package/dist/assets/hydrogen/vite/package.json +13 -0
  133. package/dist/assets/hydrogen/vite/vite.config.js +43 -0
  134. package/dist/assets/speedscope/SourceCodePro-Regular.ttf.f546cbe0.woff2 +0 -0
  135. package/dist/assets/speedscope/demangle-cpp.1768f4cc.js +4 -0
  136. package/dist/assets/speedscope/favicon-16x16.f74b3187.png +0 -0
  137. package/dist/assets/speedscope/favicon-32x32.bc503437.png +0 -0
  138. package/dist/assets/speedscope/file-format-schema.json +324 -0
  139. package/dist/assets/speedscope/import.bcbb2033.js +123 -0
  140. package/dist/assets/speedscope/index.html +2 -0
  141. package/dist/assets/speedscope/perf-vertx-stacks-01-collapsed-all.2681da68.txt +199 -0
  142. package/dist/assets/speedscope/release.txt +3 -0
  143. package/dist/assets/speedscope/reset.8c46b7a1.css +2 -0
  144. package/dist/assets/speedscope/source-code-pro.52b1676f.css +2 -0
  145. package/dist/assets/speedscope/source-code-pro.LICENSE.md +93 -0
  146. package/dist/assets/speedscope/source-map.438fa06b.js +24 -0
  147. package/dist/assets/speedscope/speedscope.6f107512.js +193 -0
  148. package/dist/babel-I2RLWM7N.js +15 -0
  149. package/dist/bootstrap.d.ts +5 -0
  150. package/dist/bootstrap.js +3 -0
  151. package/dist/chokidar-5RWEYTNQ.js +1 -0
  152. package/dist/chunk-2AK44UYM.js +1 -0
  153. package/dist/chunk-2CIZE537.js +3 -0
  154. package/dist/chunk-2EAFYCCS.js +16 -0
  155. package/dist/chunk-2KD4LHRT.js +5 -0
  156. package/dist/chunk-2KGPH7YG.js +2 -0
  157. package/dist/chunk-2O224ZPO.js +3 -0
  158. package/dist/chunk-2XDUJQQN.js +12 -0
  159. package/dist/chunk-36ROOKQB.js +1 -0
  160. package/dist/chunk-3DCN3N23.js +4 -0
  161. package/dist/chunk-3JXPOOFV.js +836 -0
  162. package/dist/chunk-4QBJ5JBX.js +18 -0
  163. package/dist/chunk-4ZNV5YSL.js +1 -0
  164. package/dist/chunk-5HBIIYSK.js +1 -0
  165. package/dist/chunk-5L63PRJL.js +2 -0
  166. package/dist/chunk-5N6HNQQ5.js +8 -0
  167. package/dist/chunk-5SEEDOQ5.js +1 -0
  168. package/dist/chunk-636CTEW7.js +1 -0
  169. package/dist/chunk-67Z34HN5.js +5 -0
  170. package/dist/chunk-6BDAJ6UD.js +5 -0
  171. package/dist/chunk-6CXG3XLP.js +1 -0
  172. package/dist/chunk-6MWWJZFN.js +19 -0
  173. package/dist/chunk-6QDOCBD4.js +6 -0
  174. package/dist/chunk-6RQOEPEC.js +1 -0
  175. package/dist/chunk-72ZY3KTF.js +1 -0
  176. package/dist/chunk-742XXXGL.js +6 -0
  177. package/dist/chunk-773TIA5M.js +2 -0
  178. package/dist/chunk-7HFHL5SO.js +2 -0
  179. package/dist/chunk-7ISJRIPT.js +1 -0
  180. package/dist/chunk-7LWUHQIF.js +1 -0
  181. package/dist/chunk-7T6M7FAC.js +103 -0
  182. package/dist/chunk-7UNQOKZW.js +1 -0
  183. package/dist/chunk-7Y7AZRL3.js +10 -0
  184. package/dist/chunk-A6BMJISP.js +8 -0
  185. package/dist/chunk-AAK376RT.js +2 -0
  186. package/dist/chunk-AEUCDGTB.js +294 -0
  187. package/dist/chunk-AWUX36VG.js +1 -0
  188. package/dist/chunk-B4OMIONW.js +5 -0
  189. package/dist/chunk-BOAGJ6P5.js +1 -0
  190. package/dist/chunk-BWJIZYAG.js +1 -0
  191. package/dist/chunk-BZ73NV3L.js +2 -0
  192. package/dist/chunk-C3RUVXG2.js +6 -0
  193. package/dist/chunk-C4YLE3NS.js +64 -0
  194. package/dist/chunk-CEYIZC3M.js +2 -0
  195. package/dist/chunk-CIWKN4HF.js +7 -0
  196. package/dist/chunk-CRALWNNO.js +1 -0
  197. package/dist/chunk-CTNBSUVU.js +83 -0
  198. package/dist/chunk-CULTZLC4.js +1 -0
  199. package/dist/chunk-CX5CC6P5.js +1 -0
  200. package/dist/chunk-CX75OKZK.js +1 -0
  201. package/dist/chunk-DASVZTAX.js +359 -0
  202. package/dist/chunk-DPNZWBT5.js +1 -0
  203. package/dist/chunk-DX3JLOUA.js +4 -0
  204. package/dist/chunk-E55KS3GZ.js +1 -0
  205. package/dist/chunk-E5FXOLQO.js +17 -0
  206. package/dist/chunk-E6N4PZZR.js +7 -0
  207. package/dist/chunk-EB574SY6.js +6 -0
  208. package/dist/chunk-ET2CGROE.js +451 -0
  209. package/dist/chunk-EX5GVHGE.js +1 -0
  210. package/dist/chunk-F3NYCSXT.js +273 -0
  211. package/dist/chunk-F3TMLDLC.js +1 -0
  212. package/dist/chunk-F6X6OXXB.js +3 -0
  213. package/dist/chunk-FDBHQLFK.js +1 -0
  214. package/dist/chunk-FDYW3UQC.js +1 -0
  215. package/dist/chunk-FEDVVYK2.js +1 -0
  216. package/dist/chunk-FFSDGRAN.js +1 -0
  217. package/dist/chunk-FJ6F4XRV.js +28 -0
  218. package/dist/chunk-FKIVKNOV.js +2 -0
  219. package/dist/chunk-FOREMLFZ.js +1 -0
  220. package/dist/chunk-FUYDGK33.js +2 -0
  221. package/dist/chunk-FX3L344E.js +1 -0
  222. package/dist/chunk-G5XIGN5D.js +593 -0
  223. package/dist/chunk-GAYKYEIM.js +1 -0
  224. package/dist/chunk-GB3YC4TI.js +1 -0
  225. package/dist/chunk-GCN4O7HM.js +1 -0
  226. package/dist/chunk-GCY7LPEF.js +6 -0
  227. package/dist/chunk-GNBRCK7L.js +3 -0
  228. package/dist/chunk-GRPKF5ZB.js +1 -0
  229. package/dist/chunk-GRSF7456.js +1 -0
  230. package/dist/chunk-H2TQ4ODI.js +1 -0
  231. package/dist/chunk-H6XEESUN.js +4 -0
  232. package/dist/chunk-HB347DXT.js +2 -0
  233. package/dist/chunk-HFSCXTJQ.js +97 -0
  234. package/dist/chunk-HHN6KZXX.js +1 -0
  235. package/dist/chunk-HP64ZTEJ.js +6 -0
  236. package/dist/chunk-I5A6BPCP.js +1 -0
  237. package/dist/chunk-IARCMH7G.js +5 -0
  238. package/dist/chunk-IBI5UCJO.js +1 -0
  239. package/dist/chunk-IKUSLRGD.js +1 -0
  240. package/dist/chunk-IT4HYLTY.js +1 -0
  241. package/dist/chunk-IWOTLFOY.js +32 -0
  242. package/dist/chunk-J3JPJCWP.js +1 -0
  243. package/dist/chunk-J4T73EAS.js +8 -0
  244. package/dist/chunk-JD5P5RAJ.js +1 -0
  245. package/dist/chunk-JG4HH54Q.js +1 -0
  246. package/dist/chunk-JIYSCWCG.js +1 -0
  247. package/dist/chunk-JJZNUFPD.js +44 -0
  248. package/dist/chunk-JLGA3B7P.js +1 -0
  249. package/dist/chunk-JWRK5KLD.js +560 -0
  250. package/dist/chunk-JX7FYWPO.js +1 -0
  251. package/dist/chunk-K42WBNJQ.js +18 -0
  252. package/dist/chunk-KDU7VW3L.js +11 -0
  253. package/dist/chunk-KWVOJWO7.js +1 -0
  254. package/dist/chunk-LANUJ7LX.js +16 -0
  255. package/dist/chunk-LD6ZCTZ3.js +9 -0
  256. package/dist/chunk-LFOBYEWG.js +1 -0
  257. package/dist/chunk-LQ7ENG4V.js +1 -0
  258. package/dist/chunk-LUKQ5HLC.js +1 -0
  259. package/dist/chunk-M2XHIN57.js +4 -0
  260. package/dist/chunk-MNOQAXJW.js +3 -0
  261. package/dist/chunk-MPW2YJWU.js +31 -0
  262. package/dist/chunk-MYQUYU4U.js +2 -0
  263. package/dist/chunk-N65F7ET2.js +1 -0
  264. package/dist/chunk-N6RBRPGW.js +7 -0
  265. package/dist/chunk-N75VOJHO.js +15 -0
  266. package/dist/chunk-NBFMP5XQ.js +1 -0
  267. package/dist/chunk-NE3ZFSMS.js +1 -0
  268. package/dist/chunk-NGLMZYS7.js +278 -0
  269. package/dist/chunk-NHAUJWEG.js +1 -0
  270. package/dist/chunk-NILETICC.js +11 -0
  271. package/dist/chunk-NNZXKFOS.js +7 -0
  272. package/dist/chunk-NQK2VCDA.js +1 -0
  273. package/dist/chunk-NROVZETL.js +1 -0
  274. package/dist/chunk-NW6NUGN7.js +1 -0
  275. package/dist/chunk-O7DZXO3O.js +15 -0
  276. package/dist/chunk-OBYQSIYU.js +25 -0
  277. package/dist/chunk-OEG3N5PG.js +15 -0
  278. package/dist/chunk-OGBZTY2G.js +5 -0
  279. package/dist/chunk-OMHR423H.js +1 -0
  280. package/dist/chunk-OV6SRRXR.js +5 -0
  281. package/dist/chunk-OVV5YGKN.js +1 -0
  282. package/dist/chunk-OZL5FTT7.js +1 -0
  283. package/dist/chunk-OZMQ2EJB.js +1 -0
  284. package/dist/chunk-P2OI2P2M.js +1 -0
  285. package/dist/chunk-P57P7UAN.js +3 -0
  286. package/dist/chunk-PATTG7YZ.js +1 -0
  287. package/dist/chunk-PG5YNPJB.js +26 -0
  288. package/dist/chunk-PP4L2JJ6.js +3 -0
  289. package/dist/chunk-Q5JX23QU.js +1 -0
  290. package/dist/chunk-Q5KVMLBK.js +4 -0
  291. package/dist/chunk-Q5LIJGT7.js +12 -0
  292. package/dist/chunk-Q6ADIMJM.js +6 -0
  293. package/dist/chunk-Q7BOSHWX.js +7 -0
  294. package/dist/chunk-QERQARMC.js +1 -0
  295. package/dist/chunk-QOV43E26.js +1 -0
  296. package/dist/chunk-QTFUYKMF.js +1 -0
  297. package/dist/chunk-QTJCCOAG.js +20 -0
  298. package/dist/chunk-R6ICQT2D.js +1 -0
  299. package/dist/chunk-R7T3LYJL.js +3 -0
  300. package/dist/chunk-RJ5VF3QY.js +2 -0
  301. package/dist/chunk-RXQJCJDV.js +1 -0
  302. package/dist/chunk-S2TLBBSS.js +5 -0
  303. package/dist/chunk-S5FOQY35.js +1 -0
  304. package/dist/chunk-SYLHT42O.js +1 -0
  305. package/dist/chunk-T4AA6TSF.js +15 -0
  306. package/dist/chunk-T4QWK5GG.js +10 -0
  307. package/dist/chunk-T7KHS6RF.js +1 -0
  308. package/dist/chunk-T7PJDT5O.js +6 -0
  309. package/dist/chunk-TEY4LRY7.js +1 -0
  310. package/dist/chunk-TFBRVLDN.js +1 -0
  311. package/dist/chunk-TOLPNBZK.js +4 -0
  312. package/dist/chunk-TR4OWSEX.js +77 -0
  313. package/dist/chunk-TU47HMTL.js +1 -0
  314. package/dist/chunk-TUVDJ3PG.js +2 -0
  315. package/dist/chunk-TYMYIUIQ.js +1 -0
  316. package/dist/chunk-U2DWBZK2.js +1 -0
  317. package/dist/chunk-U53OLUOE.js +3 -0
  318. package/dist/chunk-UAETNFN4.js +1 -0
  319. package/dist/chunk-UAFEFKAQ.js +5 -0
  320. package/dist/chunk-ULRJDKWQ.js +1 -0
  321. package/dist/chunk-UOHNRH6E.js +7 -0
  322. package/dist/chunk-UZARYOLN.js +1 -0
  323. package/dist/chunk-VASGXHYA.js +1 -0
  324. package/dist/chunk-VD4XJ6BX.js +1 -0
  325. package/dist/chunk-VE35YELD.js +1 -0
  326. package/dist/chunk-VFM2KQRM.js +19 -0
  327. package/dist/chunk-VJEKDBGZ.js +1 -0
  328. package/dist/chunk-VKWPEFWQ.js +1 -0
  329. package/dist/chunk-VSDRNYA5.js +1 -0
  330. package/dist/chunk-VUMUCNI7.js +1 -0
  331. package/dist/chunk-VVZSYHDG.js +4 -0
  332. package/dist/chunk-VXEYO3ZP.js +1 -0
  333. package/dist/chunk-VYDSOAV4.js +9 -0
  334. package/dist/chunk-W6ST525S.js +99 -0
  335. package/dist/chunk-WBYAGS6B.js +6 -0
  336. package/dist/chunk-WGAFCKGD.js +1 -0
  337. package/dist/chunk-WYBTC356.js +1 -0
  338. package/dist/chunk-XF2KTEID.js +1 -0
  339. package/dist/chunk-XH5YGJQR.js +1 -0
  340. package/dist/chunk-XHKWITLA.js +1705 -0
  341. package/dist/chunk-XOCB4KNX.js +2 -0
  342. package/dist/chunk-XUUAKGEX.js +1 -0
  343. package/dist/chunk-XUYVJEZG.js +3 -0
  344. package/dist/chunk-Y47C3LSX.js +3 -0
  345. package/dist/chunk-Y5PRPHLQ.js +6 -0
  346. package/dist/chunk-YD2VQEN5.js +1 -0
  347. package/dist/chunk-YESGYUEL.js +1 -0
  348. package/dist/chunk-YEVGLC5X.js +1 -0
  349. package/dist/chunk-YFINLODF.js +375 -0
  350. package/dist/chunk-YKL3BLWC.js +46 -0
  351. package/dist/chunk-YLQ3LNNY.js +99 -0
  352. package/dist/chunk-YLXPYXQP.js +1 -0
  353. package/dist/chunk-YNDIZCD2.js +7 -0
  354. package/dist/chunk-YPWHD3NL.js +1 -0
  355. package/dist/chunk-YSAFHVV6.js +8 -0
  356. package/dist/chunk-YY6TFARF.js +1 -0
  357. package/dist/chunk-YZMY2CTU.js +10 -0
  358. package/dist/chunk-Z4AFEO36.js +1 -0
  359. package/dist/chunk-Z5WPP6ME.js +1 -0
  360. package/dist/chunk-Z65E4UAP.js +1 -0
  361. package/dist/chunk-ZDF5N422.js +1 -0
  362. package/dist/chunk-ZDRIQC7O.js +1 -0
  363. package/dist/chunk-ZH44BDUR.js +5 -0
  364. package/dist/chunk-ZI7LK3LW.js +11 -0
  365. package/dist/chunk-ZL5LU4U2.js +32 -0
  366. package/dist/chunk-ZYX7UHCQ.js +1 -0
  367. package/dist/chunk-ZZRFG6ME.js +317 -0
  368. package/dist/cli/commands/app/app-logs/sources.js +1 -0
  369. package/dist/cli/commands/app/build.js +1 -0
  370. package/dist/cli/commands/app/bulk/cancel.js +1 -0
  371. package/dist/cli/commands/app/bulk/execute.js +1 -0
  372. package/dist/cli/commands/app/bulk/status.js +1 -0
  373. package/dist/cli/commands/app/config/link.js +1 -0
  374. package/dist/cli/commands/app/config/pull.js +1 -0
  375. package/dist/cli/commands/app/config/use.js +1 -0
  376. package/dist/cli/commands/app/config/validate.js +1 -0
  377. package/dist/cli/commands/app/demo/watcher.js +1 -0
  378. package/dist/cli/commands/app/deploy.js +1 -0
  379. package/dist/cli/commands/app/dev/clean.js +1 -0
  380. package/dist/cli/commands/app/dev.js +1 -0
  381. package/dist/cli/commands/app/doctor/instructions.js +1 -0
  382. package/dist/cli/commands/app/doctor.js +1 -0
  383. package/dist/cli/commands/app/env/pull.js +1 -0
  384. package/dist/cli/commands/app/env/show.js +1 -0
  385. package/dist/cli/commands/app/execute.js +1 -0
  386. package/dist/cli/commands/app/function/build.js +1 -0
  387. package/dist/cli/commands/app/function/info.js +1 -0
  388. package/dist/cli/commands/app/function/replay.js +1 -0
  389. package/dist/cli/commands/app/function/run.js +1 -0
  390. package/dist/cli/commands/app/function/schema.js +1 -0
  391. package/dist/cli/commands/app/function/typegen.js +1 -0
  392. package/dist/cli/commands/app/generate/extension.js +1 -0
  393. package/dist/cli/commands/app/graphiql.js +1 -0
  394. package/dist/cli/commands/app/import-custom-data-definitions.js +1 -0
  395. package/dist/cli/commands/app/import-extensions.js +1 -0
  396. package/dist/cli/commands/app/info.js +1 -0
  397. package/dist/cli/commands/app/init.js +1 -0
  398. package/dist/cli/commands/app/logs.js +1 -0
  399. package/dist/cli/commands/app/release.js +1 -0
  400. package/dist/cli/commands/app/subscription-migrations/cancel.js +1 -0
  401. package/dist/cli/commands/app/subscription-migrations/list.js +1 -0
  402. package/dist/cli/commands/app/subscription-migrations/schedule.js +1 -0
  403. package/dist/cli/commands/app/subscription-migrations/status.js +1 -0
  404. package/dist/cli/commands/app/subscription-migrations/unschedule.js +1 -0
  405. package/dist/cli/commands/app/versions/list.js +1 -0
  406. package/dist/cli/commands/app/webhook/trigger.js +1 -0
  407. package/dist/cli/commands/auth/login.d.ts +8 -0
  408. package/dist/cli/commands/auth/login.js +1 -0
  409. package/dist/cli/commands/auth/logout.d.ts +5 -0
  410. package/dist/cli/commands/auth/logout.js +1 -0
  411. package/dist/cli/commands/cache/clear.d.ts +6 -0
  412. package/dist/cli/commands/cache/clear.js +1 -0
  413. package/dist/cli/commands/config/autoupgrade/constants.d.ts +4 -0
  414. package/dist/cli/commands/config/autoupgrade/constants.js +1 -0
  415. package/dist/cli/commands/config/autoupgrade/off.d.ts +7 -0
  416. package/dist/cli/commands/config/autoupgrade/off.js +1 -0
  417. package/dist/cli/commands/config/autoupgrade/on.d.ts +7 -0
  418. package/dist/cli/commands/config/autoupgrade/on.js +1 -0
  419. package/dist/cli/commands/config/autoupgrade/status.d.ts +7 -0
  420. package/dist/cli/commands/config/autoupgrade/status.js +1 -0
  421. package/dist/cli/commands/debug/command-flags.d.ts +9 -0
  422. package/dist/cli/commands/debug/command-flags.js +1 -0
  423. package/dist/cli/commands/doc/fetch.d.ts +12 -0
  424. package/dist/cli/commands/doc/fetch.js +1 -0
  425. package/dist/cli/commands/doc/search.d.ts +13 -0
  426. package/dist/cli/commands/doc/search.js +1 -0
  427. package/dist/cli/commands/docs/generate.d.ts +21 -0
  428. package/dist/cli/commands/docs/generate.js +1 -0
  429. package/dist/cli/commands/doctor-release/doctor-release.d.ts +6 -0
  430. package/dist/cli/commands/doctor-release/doctor-release.js +1 -0
  431. package/dist/cli/commands/doctor-release/theme/index.d.ts +14 -0
  432. package/dist/cli/commands/doctor-release/theme/index.js +1 -0
  433. package/dist/cli/commands/help.d.ts +13 -0
  434. package/dist/cli/commands/help.js +1 -0
  435. package/dist/cli/commands/kitchen-sink/async.d.ts +11 -0
  436. package/dist/cli/commands/kitchen-sink/async.js +1 -0
  437. package/dist/cli/commands/kitchen-sink/index.d.ts +12 -0
  438. package/dist/cli/commands/kitchen-sink/index.js +1 -0
  439. package/dist/cli/commands/kitchen-sink/prompts.d.ts +11 -0
  440. package/dist/cli/commands/kitchen-sink/prompts.js +1 -0
  441. package/dist/cli/commands/kitchen-sink/static.d.ts +11 -0
  442. package/dist/cli/commands/kitchen-sink/static.js +1 -0
  443. package/dist/cli/commands/notifications/generate.d.ts +6 -0
  444. package/dist/cli/commands/notifications/generate.js +1 -0
  445. package/dist/cli/commands/notifications/list.d.ts +9 -0
  446. package/dist/cli/commands/notifications/list.js +1 -0
  447. package/dist/cli/commands/organization/list.js +1 -0
  448. package/dist/cli/commands/search.d.ts +14 -0
  449. package/dist/cli/commands/search.js +1 -0
  450. package/dist/cli/commands/send-analytics.d.ts +5 -0
  451. package/dist/cli/commands/send-analytics.js +1 -0
  452. package/dist/cli/commands/theme/check.js +1 -0
  453. package/dist/cli/commands/theme/console.js +1 -0
  454. package/dist/cli/commands/theme/delete.js +1 -0
  455. package/dist/cli/commands/theme/dev.js +1 -0
  456. package/dist/cli/commands/theme/duplicate.js +1 -0
  457. package/dist/cli/commands/theme/info.js +1 -0
  458. package/dist/cli/commands/theme/init.js +1 -0
  459. package/dist/cli/commands/theme/language-server.js +1 -0
  460. package/dist/cli/commands/theme/list.js +1 -0
  461. package/dist/cli/commands/theme/metafields/pull.js +1 -0
  462. package/dist/cli/commands/theme/open.js +1 -0
  463. package/dist/cli/commands/theme/package.js +1 -0
  464. package/dist/cli/commands/theme/preview.js +1 -0
  465. package/dist/cli/commands/theme/profile.js +1 -0
  466. package/dist/cli/commands/theme/publish.js +1 -0
  467. package/dist/cli/commands/theme/pull.js +1 -0
  468. package/dist/cli/commands/theme/push.js +1 -0
  469. package/dist/cli/commands/theme/rename.js +1 -0
  470. package/dist/cli/commands/theme/share.js +1 -0
  471. package/dist/cli/commands/upgrade.d.ts +7 -0
  472. package/dist/cli/commands/upgrade.js +1 -0
  473. package/dist/cli/commands/version.d.ts +5 -0
  474. package/dist/cli/commands/version.js +1 -0
  475. package/dist/cli/help.d.ts +38 -0
  476. package/dist/cli/help.js +2 -0
  477. package/dist/cli/services/commands/doc/fetch.d.ts +1 -0
  478. package/dist/cli/services/commands/doc/fetch.js +45 -0
  479. package/dist/cli/services/commands/doc/search.d.ts +1 -0
  480. package/dist/cli/services/commands/doc/search.js +47 -0
  481. package/dist/cli/services/commands/notifications.d.ts +2 -0
  482. package/dist/cli/services/commands/notifications.js +106 -0
  483. package/dist/cli/services/commands/search.d.ts +1 -0
  484. package/dist/cli/services/commands/search.js +7 -0
  485. package/dist/cli/services/commands/version.d.ts +1 -0
  486. package/dist/cli/services/commands/version.js +6 -0
  487. package/dist/cli/services/doctor-release/context.d.ts +16 -0
  488. package/dist/cli/services/doctor-release/context.js +11 -0
  489. package/dist/cli/services/doctor-release/theme/runner.d.ts +7 -0
  490. package/dist/cli/services/doctor-release/theme/runner.js +37 -0
  491. package/dist/cli/services/doctor-release/theme/tests/init.d.ts +11 -0
  492. package/dist/cli/services/doctor-release/theme/tests/init.js +34 -0
  493. package/dist/cli/services/doctor-release/theme/tests/push.d.ts +10 -0
  494. package/dist/cli/services/doctor-release/theme/tests/push.js +44 -0
  495. package/dist/cli/services/kitchen-sink/async.d.ts +1 -0
  496. package/dist/cli/services/kitchen-sink/async.js +65 -0
  497. package/dist/cli/services/kitchen-sink/prompts.d.ts +1 -0
  498. package/dist/cli/services/kitchen-sink/prompts.js +168 -0
  499. package/dist/cli/services/kitchen-sink/static.d.ts +1 -0
  500. package/dist/cli/services/kitchen-sink/static.js +201 -0
  501. package/dist/command-registry.d.ts +8 -0
  502. package/dist/command-registry.js +1 -0
  503. package/dist/conf-store-ASDCTDQ4.js +1 -0
  504. package/dist/configs/all.yml +280 -0
  505. package/dist/configs/nothing.yml +3 -0
  506. package/dist/configs/recommended.yml +258 -0
  507. package/dist/configs/theme-app-extension.yml +24 -0
  508. package/dist/custom-oclif-loader-BWAMUFQ4.js +1 -0
  509. package/dist/data/app_block_entry.json +13 -0
  510. package/dist/data/default_setting_values.json +24 -0
  511. package/dist/data/filters.json +6177 -0
  512. package/dist/data/latest.json +2 -0
  513. package/dist/data/local_block_entry.json +25 -0
  514. package/dist/data/manifest_theme.json +19 -0
  515. package/dist/data/manifest_theme_app_extension.json +10 -0
  516. package/dist/data/objects.json +20621 -0
  517. package/dist/data/preset.json +72 -0
  518. package/dist/data/preset_blocks.json +91 -0
  519. package/dist/data/section.json +208 -0
  520. package/dist/data/setting.json +1538 -0
  521. package/dist/data/settings.json +10 -0
  522. package/dist/data/shopify_system_translations.json +2766 -0
  523. package/dist/data/tags.json +1276 -0
  524. package/dist/data/targetted_block_entry.json +15 -0
  525. package/dist/data/theme_block.json +91 -0
  526. package/dist/data/theme_block_entry.json +14 -0
  527. package/dist/data/theme_settings.json +83 -0
  528. package/dist/data/translations.json +63 -0
  529. package/dist/deprecations-VBQV7Q4O.js +1 -0
  530. package/dist/devtools-37DE4MUR.js +1 -0
  531. package/dist/devtools-WAWU5KQL.js +1 -0
  532. package/dist/dist-FZLOAKU7.js +1 -0
  533. package/dist/dist-HTY6UHG5.js +1 -0
  534. package/dist/environments-HSTNEQRG.js +1 -0
  535. package/dist/error-2LZYKRMA.js +1 -0
  536. package/dist/error-handler-PIGEJ7BT.js +1 -0
  537. package/dist/estree-JV5M77BA.js +44 -0
  538. package/dist/flow-N4JYPYMQ.js +20 -0
  539. package/dist/fs-BJHNJDDK.js +1 -0
  540. package/dist/glimmer-JEV3BXHR.js +37 -0
  541. package/dist/graphql-DTF6MHYF.js +28 -0
  542. package/dist/hooks/did-you-mean.d.ts +1 -0
  543. package/dist/hooks/did-you-mean.js +1 -0
  544. package/dist/hooks/hydrogen-init.d.ts +7 -0
  545. package/dist/hooks/hydrogen-init.js +1 -0
  546. package/dist/hooks/plugin-plugins.d.ts +1 -0
  547. package/dist/hooks/plugin-plugins.js +1 -0
  548. package/dist/hooks/postrun.d.ts +1 -0
  549. package/dist/hooks/postrun.js +1 -0
  550. package/dist/hooks/prerun.d.ts +1 -0
  551. package/dist/hooks/prerun.js +2 -0
  552. package/dist/hooks/public-metadata.d.ts +1 -0
  553. package/dist/hooks/public-metadata.js +1 -0
  554. package/dist/hooks/sensitive-metadata.d.ts +1 -0
  555. package/dist/hooks/sensitive-metadata.js +1 -0
  556. package/dist/hooks/tunnel-provider.d.ts +1 -0
  557. package/dist/hooks/tunnel-provider.js +1 -0
  558. package/dist/hooks/tunnel-start.d.ts +1 -0
  559. package/dist/hooks/tunnel-start.js +1 -0
  560. package/dist/html-LVOJ3RQS.js +25 -0
  561. package/dist/http-proxy-node16-A6AKKRQH.js +38 -0
  562. package/dist/index.d.ts +13 -0
  563. package/dist/index.js +120 -0
  564. package/dist/is-global-6SCOAJVG.js +1 -0
  565. package/dist/latest-version-LDWU5F7A.js +49 -0
  566. package/dist/lib-2BR2WN7L.js +1 -0
  567. package/dist/lib-M72BVWQ3.js +1 -0
  568. package/dist/lib-O5EZ4NVT.js +1 -0
  569. package/dist/lib-P3APEIHY.js +1 -0
  570. package/dist/local-PZWPRFU7.js +1 -0
  571. package/dist/markdown-J6CE6POI.js +62 -0
  572. package/dist/meriyah-PNQQZQYI.js +5 -0
  573. package/dist/metadata-VVBHB3HL.js +1 -0
  574. package/dist/morph-BMYYMQNX.js +30489 -0
  575. package/dist/multipart-parser-5NSSTW27.js +2 -0
  576. package/dist/node-package-manager-ETYQN7OM.js +1 -0
  577. package/dist/notifications-system-652OG5KL.js +1 -0
  578. package/dist/npa-A4YSCQ5Q.js +1 -0
  579. package/dist/open-KLSGXBIW.js +1 -0
  580. package/dist/os-7D6NT4O3.js +1 -0
  581. package/dist/out-53ABAVL7.js +1 -0
  582. package/dist/output-74VDGYJD.js +1 -0
  583. package/dist/path-MBXP7ZIC.js +1 -0
  584. package/dist/postcss-Q36SHOML.js +61 -0
  585. package/dist/prettier-EGVCP5CY.js +1 -0
  586. package/dist/source-map-E7FCCJL7.js +1 -0
  587. package/dist/system-P5QIJALL.js +1 -0
  588. package/dist/templates/ui-extensions/html/error.html.liquid +41 -0
  589. package/dist/templates/ui-extensions/html/post_purchase/index.html.liquid +44 -0
  590. package/dist/templates/ui-extensions/html/post_purchase/tunnel-error.html.liquid +41 -0
  591. package/dist/templates/ui-extensions/html/tunnel-error.html.liquid +55 -0
  592. package/dist/toml_patch_bg.wasm +0 -0
  593. package/dist/tsconfig.tsbuildinfo +1 -0
  594. package/dist/typescript-5R4Y7PXE.js +1 -0
  595. package/dist/typescript-WYPDGPSV.js +21 -0
  596. package/dist/ui-H5I5YVKV.js +1 -0
  597. package/dist/upgrade-34HSYBXI.js +1 -0
  598. package/dist/vendor/esbuild-ohos/lib/main.js +2538 -0
  599. package/dist/vendor/esbuild-ohos/package.json +7 -0
  600. package/dist/version-EKXEAF6Q.js +1 -0
  601. package/dist/version-J2PYO6M5.js +1 -0
  602. package/dist/workerd-X4TGHEG3.js +18 -0
  603. package/dist/yaml-6KWCJ64X.js +159 -0
  604. package/dist/yoga.wasm +0 -0
  605. package/oclif.manifest.json +10100 -0
  606. package/package.json +153 -0
@@ -0,0 +1,2839 @@
1
+ # skeleton
2
+
3
+ ## 2026.4.6
4
+
5
+ ### Patch Changes
6
+
7
+ - Recommend the Shopify AI Toolkit in newly scaffolded storefronts. ([#3887](https://github.com/Shopify/hydrogen/pull/3887)) by [@gonzaloriestra](https://github.com/gonzaloriestra)
8
+
9
+ - Updated dependencies [[`10356c92fc1d4335244db7304cc6cdd47ba5c892`](https://github.com/Shopify/hydrogen/commit/10356c92fc1d4335244db7304cc6cdd47ba5c892), [`f15667f98826650f3904597b61b5dcb5f8b51c0a`](https://github.com/Shopify/hydrogen/commit/f15667f98826650f3904597b61b5dcb5f8b51c0a)]:
10
+ - @shopify/hydrogen@2026.4.5
11
+
12
+ ## 2026.4.5
13
+
14
+ ### Patch Changes
15
+
16
+ - Add an explicit `~` app alias to new Hydrogen projects. ([#3852](https://github.com/Shopify/hydrogen/pull/3852)) by [@andguy95](https://github.com/andguy95)
17
+
18
+ JavaScript projects use `jsconfig.json`, which is not reliably covered by Vite's native `resolve.tsconfigPaths` behavior. New projects now define Hydrogen's `~/` import convention directly in the Vite config so imports like `~/assets/favicon.svg` work in both TypeScript and JavaScript projects.
19
+
20
+ ## 2026.4.4
21
+
22
+ ### Patch Changes
23
+
24
+ - Updated dependencies [[`23431c956193420bce3442e9e5cc711dc95cc497`](https://github.com/Shopify/hydrogen/commit/23431c956193420bce3442e9e5cc711dc95cc497)]:
25
+ - @shopify/hydrogen@2026.4.4
26
+
27
+ ## 2026.4.3
28
+
29
+ ### Patch Changes
30
+
31
+ - Include line item children recursively in cart. ([#3753](https://github.com/Shopify/hydrogen/pull/3753)) by [@martin-pettersson](https://github.com/martin-pettersson)
32
+
33
+ - Add generic cart result typing to `createCartHandler` so custom cart fragments can use their generated fragment types. ([#3767](https://github.com/Shopify/hydrogen/pull/3767)) by [@andguy95](https://github.com/andguy95)
34
+
35
+ - Widen React Router peer dependency ranges so Hydrogen packages accept compatible React Router 7.16 patch versions without npm peer dependency conflicts. New Hydrogen projects now default to React Router 7.16.0. ([#3771](https://github.com/Shopify/hydrogen/pull/3771)) by [@fredericoo](https://github.com/fredericoo)
36
+
37
+ - Updated dependencies [[`3ccc22e0a3407298e835104e29adfb036f261474`](https://github.com/Shopify/hydrogen/commit/3ccc22e0a3407298e835104e29adfb036f261474), [`a810db483c108ac8bbeaac45595b130ed95a2ec7`](https://github.com/Shopify/hydrogen/commit/a810db483c108ac8bbeaac45595b130ed95a2ec7), [`d17057eb4630710743e81b83573973100ec56d23`](https://github.com/Shopify/hydrogen/commit/d17057eb4630710743e81b83573973100ec56d23), [`995190036d99e02ba6fb559b8e3c406c90043599`](https://github.com/Shopify/hydrogen/commit/995190036d99e02ba6fb559b8e3c406c90043599), [`39f2b326e9fddda36b1d12149794bf4ffcc0d4b8`](https://github.com/Shopify/hydrogen/commit/39f2b326e9fddda36b1d12149794bf4ffcc0d4b8)]:
38
+ - @shopify/hydrogen@2026.4.3
39
+
40
+ ## 2026.4.2
41
+
42
+ ### Patch Changes
43
+
44
+ - Add support for Vite 7 and Vite 8. Hydrogen remains backwards-compatible with Vite 5+. ([#3617](https://github.com/Shopify/hydrogen/pull/3617)) by [@frandiox](https://github.com/frandiox)
45
+
46
+ Mini Oxygen's dev server has been refactored to use the [Vite Environment API](https://vite.dev/guide/api-environment), which is the standard way to run non-browser runtimes in Vite. This replaces the previous custom middleware approach with a first-class `FetchableDevEnvironment`, improving compatibility with Vite's built-in HMR and module invalidation.
47
+
48
+ New Hydrogen projects created with `npm create @shopify/hydrogen` will default to Vite 8. The `vite-tsconfig-paths` plugin is no longer needed in the skeleton template since Vite 8 supports `resolve.tsconfigPaths` natively.
49
+
50
+ - Updated dependencies [[`dc49699c799997d5893bc06e444f888e86a3bc29`](https://github.com/Shopify/hydrogen/commit/dc49699c799997d5893bc06e444f888e86a3bc29), [`50df825c57159757529f5f9f62c258d4de2a4b97`](https://github.com/Shopify/hydrogen/commit/50df825c57159757529f5f9f62c258d4de2a4b97), [`51f1e77fe63be5e5ded4ef0c91942bc304f1abc4`](https://github.com/Shopify/hydrogen/commit/51f1e77fe63be5e5ded4ef0c91942bc304f1abc4)]:
51
+ - @shopify/hydrogen@2026.4.2
52
+
53
+ ## 2026.4.1
54
+
55
+ ### Patch Changes
56
+
57
+ - Fix `set-cookie-parser` and `cookie` resolution warnings during `dev` by using Vite's nested dependency syntax (`react-router > dep`). These are CJS transitive dependencies of `react-router` that weren't resolvable by bare name with strict package managers like pnpm. ([#3698](https://github.com/Shopify/hydrogen/pull/3698)) by [@fredericoo](https://github.com/fredericoo)
58
+
59
+ - Updated dependencies [[`f84ab400c62d89827574d0fa65ba310a2e75f36f`](https://github.com/Shopify/hydrogen/commit/f84ab400c62d89827574d0fa65ba310a2e75f36f)]:
60
+ - @shopify/hydrogen@2026.4.1
61
+
62
+ ## 2026.4.0
63
+
64
+ ### Major Changes
65
+
66
+ - Update Storefront API and Customer Account API from 2026-01 to 2026-04. ([#3651](https://github.com/Shopify/hydrogen/pull/3651)) by [@itsjustriley](https://github.com/itsjustriley)
67
+
68
+ ## Breaking changes
69
+
70
+ **JSON metafield values limited to 128KB**: When using API version 2026-04 or later, the Storefront API limits JSON type metafield writes to 128KB. This limit applies at the API level - Hydrogen passes through to the Storefront API without additional restriction. Apps that used JSON metafields before April 1, 2026 are grandfathered at the existing 2MB limit. Large metafield values continue to be readable by all API versions.
71
+
72
+ ## New features
73
+
74
+ **New `MERCHANDISE_LINE_TRANSFORMERS_RUN_ERROR` cart error code**: Cart operations (`cartCreate`, `cartLinesAdd`, etc.) now return a specific `MERCHANDISE_LINE_TRANSFORMERS_RUN_ERROR` error code when a Cart Transform Function fails at runtime, instead of the previous generic `INVALID` error code. If you handle cart errors in your storefront code, you may want to add handling for this new code.
75
+
76
+ ## Changelog links
77
+ - [Storefront API 2026-04 changelog](https://shopify.dev/changelog?filter=api&api_version=2026-04&api_type=storefront-graphql)
78
+ - [Customer Account API 2026-04 changelog](https://shopify.dev/changelog?filter=api&api_version=2026-04&api_type=customer-account-graphql)
79
+
80
+ ### Patch Changes
81
+
82
+ - Updated dependencies [[`e7215ed0d7a74cacfa8c935f414c1cf32fc2ccd0`](https://github.com/Shopify/hydrogen/commit/e7215ed0d7a74cacfa8c935f414c1cf32fc2ccd0), [`92ab8e8b59807bbdb5dbecaa18629292d5566135`](https://github.com/Shopify/hydrogen/commit/92ab8e8b59807bbdb5dbecaa18629292d5566135), [`b0caa5c013380c7837f049f48da089a1671e2c6d`](https://github.com/Shopify/hydrogen/commit/b0caa5c013380c7837f049f48da089a1671e2c6d)]:
83
+ - @shopify/hydrogen@2026.4.0
84
+
85
+ ## 2026.1.4
86
+
87
+ ### Patch Changes
88
+
89
+ - Remove redundant Storefront API proxy route from skeleton template. The server now automatically proxies requests to `/api/:version/graphql.json` via `createRequestHandler` with `proxyStandardRoutes: true` (enabled by default since December 2025). ([#3572](https://github.com/Shopify/hydrogen/pull/3572)) by [@itsjustriley](https://github.com/itsjustriley)
90
+
91
+ Developers no longer need a manual route file for the tokenless Storefront API. Existing apps with this route can safely delete it - the server-level proxy provides the same functionality with better cookie forwarding and analytics integration.
92
+
93
+ - Updated dependencies [[`b0a75c1d759706931876f056662de2497cb3e688`](https://github.com/Shopify/hydrogen/commit/b0a75c1d759706931876f056662de2497cb3e688), [`a44ee3566b9bb9a7f43f05dfaae6f1f2ab1d548f`](https://github.com/Shopify/hydrogen/commit/a44ee3566b9bb9a7f43f05dfaae6f1f2ab1d548f)]:
94
+ - @shopify/hydrogen@2026.1.4
95
+
96
+ ## 2026.1.3
97
+
98
+ ### Patch Changes
99
+
100
+ - Improve screen reader experience for paginated product grids by hiding decorative arrow characters from assistive technology. ([#3557](https://github.com/Shopify/hydrogen/pull/3557)) by [@itsjustriley](https://github.com/itsjustriley)
101
+
102
+ - Fix broken `aria-label` on territory code input in address form. The label was the raw developer string `"territoryCode"` instead of a human-readable `"Country code"`. ([#3607](https://github.com/Shopify/hydrogen/pull/3607)) by [@itsjustriley](https://github.com/itsjustriley)
103
+
104
+ - Add aria-label to ProductPrice for improved screen reader accessibility ([#3558](https://github.com/Shopify/hydrogen/pull/3558)) by [@itsjustriley](https://github.com/itsjustriley)
105
+
106
+ - Updated dependencies [[`108243003a7f36349a446478f4e8ab0cade3e13a`](https://github.com/Shopify/hydrogen/commit/108243003a7f36349a446478f4e8ab0cade3e13a)]:
107
+ - @shopify/hydrogen@2026.1.3
108
+
109
+ ## 2026.1.2
110
+
111
+ ### Patch Changes
112
+
113
+ - Improve gift card accessibility in Skeleton template ([#3518](https://github.com/Shopify/hydrogen/pull/3518)) by [@itsjustriley](https://github.com/itsjustriley)
114
+
115
+ - Updated shopify/cli dependencies for cli-hydrogen ([#3553](https://github.com/Shopify/hydrogen/pull/3553)) by [@andguy95](https://github.com/andguy95)
116
+
117
+ - Updated loaders that used `customerAccount.handleAuthStatus()` to now await it. ([#3523](https://github.com/Shopify/hydrogen/pull/3523)) by [@fredericoo](https://github.com/fredericoo)
118
+
119
+ ### Migration
120
+
121
+ If you call `handleAuthStatus()` in your own loaders, update those callsites to use `await`.
122
+
123
+ - Updated dependencies [[`16b0e7baca0dfd1fb330d12dac924c7593d169a8`](https://github.com/Shopify/hydrogen/commit/16b0e7baca0dfd1fb330d12dac924c7593d169a8), [`1c19b87782818dbdb4252754d2d44eb9a44fe50f`](https://github.com/Shopify/hydrogen/commit/1c19b87782818dbdb4252754d2d44eb9a44fe50f), [`029fa2d0e2297f67b37c650ba8e875ee5dee81b3`](https://github.com/Shopify/hydrogen/commit/029fa2d0e2297f67b37c650ba8e875ee5dee81b3)]:
124
+ - @shopify/hydrogen@2026.1.2
125
+
126
+ ## 2026.1.1
127
+
128
+ ### Patch Changes
129
+
130
+ - Added a notice with relevant information on how to link a store in case there is no store linked yet ([#3448](https://github.com/Shopify/hydrogen/pull/3448)) by [@fredericoo](https://github.com/fredericoo)
131
+
132
+ - Fixed an issue where users without addresses could not add the first one ([#3456](https://github.com/Shopify/hydrogen/pull/3456)) by [@fredericoo](https://github.com/fredericoo)
133
+
134
+ - Updated dependencies [[`ff93a1daf2207e52e1f8331f9ff2ccd1f9b7fed6`](https://github.com/Shopify/hydrogen/commit/ff93a1daf2207e52e1f8331f9ff2ccd1f9b7fed6)]:
135
+ - @shopify/hydrogen@2026.1.1
136
+
137
+ ## 2026.1.0
138
+
139
+ ### Major Changes
140
+
141
+ - Updated to Storefront API 2026-01 and Customer Account API 2026-01. ([#3434](https://github.com/Shopify/hydrogen/pull/3434)) by [@kdaviduik](https://github.com/kdaviduik)
142
+
143
+ This is a quarterly API version update aligned with Shopify's API release schedule.
144
+
145
+ **Action Required**: The `cartDiscountCodesUpdate` mutation now requires the `discountCodes` argument. If you have custom cart discount code logic, verify your mutations include this field.
146
+
147
+ Review the changelogs for other changes that may affect your storefront:
148
+ - [Storefront API 2026-01 changelog](https://shopify.dev/changelog?filter=api&api_version=2026-01&api_type=storefront-graphql)
149
+ - [Customer Account API 2026-01 changelog](https://shopify.dev/changelog?filter=api&api_version=2026-01&api_type=customer-account-graphql)
150
+
151
+ ### Patch Changes
152
+
153
+ - Updated dependencies [[`d46c8864aea059cac7dda4871a565f76a04b1495`](https://github.com/Shopify/hydrogen/commit/d46c8864aea059cac7dda4871a565f76a04b1495)]:
154
+ - @shopify/hydrogen@2026.0.0
155
+
156
+ ## 2025.10.1
157
+
158
+ ### Major Changes
159
+
160
+ - Update Storefront API and Customer Account API to version 2025-10 ([#3430](https://github.com/Shopify/hydrogen/pull/3430)) by [@kdaviduik](https://github.com/kdaviduik)
161
+
162
+ ### Patch Changes
163
+
164
+ - Add support for Bun's text-based lockfile (`bun.lock`) introduced in Bun 1.2, and npm's shrinkwrap lockfile (`npm-shrinkwrap.json`), as alternatives to their respective primary lockfiles (`bun.lockb` and `package-lock.json`). ([#3430](https://github.com/Shopify/hydrogen/pull/3430)) by [@kdaviduik](https://github.com/kdaviduik)
165
+
166
+ - Add `cartGiftCardCodesAdd` mutation ([#3430](https://github.com/Shopify/hydrogen/pull/3430)) by [@kdaviduik](https://github.com/kdaviduik)
167
+
168
+ ## New Feature: cartGiftCardCodesAdd
169
+
170
+ The skeleton template has been updated to use the new `cartGiftCardCodesAdd` mutation:
171
+ - Removed `UpdateGiftCardForm` component from `CartSummary.tsx`
172
+ - Added `AddGiftCardForm` component using `CartForm.ACTIONS.GiftCardCodesAdd`
173
+
174
+ If you customized the gift card form in your project, you may want to migrate to the new `Add` action for simpler code.
175
+
176
+ ## Usage
177
+
178
+ ```typescript
179
+ import {CartForm} from '@shopify/hydrogen';
180
+
181
+ <CartForm action={CartForm.ACTIONS.GiftCardCodesAdd} inputs={{giftCardCodes: ['CODE1', 'CODE2']}}>
182
+ <button>Add Gift Cards</button>
183
+ </CartForm>
184
+ ```
185
+
186
+ Or with createCartHandler:
187
+
188
+ ```typescript
189
+ const cart = createCartHandler({storefront, getCartId, setCartId});
190
+ await cart.addGiftCardCodes(['SUMMER2025', 'WELCOME10']);
191
+ ```
192
+
193
+ - Add support for nested cart line items (warranties, gift wrapping, etc.) ([#3430](https://github.com/Shopify/hydrogen/pull/3430)) by [@kdaviduik](https://github.com/kdaviduik)
194
+
195
+ Storefront API 2025-10 introduces `parentRelationship` on cart line items, enabling parent-child relationships for add-ons. This update displays nested line items in the cart.
196
+
197
+ ### Changes
198
+ - Updates GraphQL fragments to include `parentRelationship` and `lineComponents` fields
199
+ - Updates `CartMain` and `CartLineItem` to render child line items with visual hierarchy
200
+
201
+ ### Note
202
+
203
+ This update focuses on **displaying** nested line items. To add both a product and its child (e.g., warranty) in a single action:
204
+
205
+ ```tsx
206
+ <AddToCartButton
207
+ lines={[
208
+ {merchandiseId: 'gid://shopify/ProductVariant/laptop-456', quantity: 1},
209
+ {
210
+ merchandiseId: 'gid://shopify/ProductVariant/warranty-123',
211
+ quantity: 1,
212
+ parent: {merchandiseId: 'gid://shopify/ProductVariant/laptop-456'},
213
+ },
214
+ ]}
215
+ >
216
+ Add to Cart with Warranty
217
+ </AddToCartButton>
218
+ ```
219
+
220
+ - Updated dependencies [[`722915130410086bc7af22215ba57ee77aa14156`](https://github.com/Shopify/hydrogen/commit/722915130410086bc7af22215ba57ee77aa14156)]:
221
+ - @shopify/hydrogen@2025.10.1
222
+
223
+ ## 2025.10.0
224
+
225
+ ### Patch Changes
226
+
227
+ - Updated dependencies [[`cd653456fbd1e7e1ab1f6fecff04c89a74b6cad9`](https://github.com/Shopify/hydrogen/commit/cd653456fbd1e7e1ab1f6fecff04c89a74b6cad9), [`24d26ad94e90ab0a859c274838f7f31e75a7808c`](https://github.com/Shopify/hydrogen/commit/24d26ad94e90ab0a859c274838f7f31e75a7808c), [`13a6f8987ea20d33a30a9c0329d7c11528b892ea`](https://github.com/Shopify/hydrogen/commit/13a6f8987ea20d33a30a9c0329d7c11528b892ea), [`403c1f5b6e266c3dfad30f7cfed229e3304570b0`](https://github.com/Shopify/hydrogen/commit/403c1f5b6e266c3dfad30f7cfed229e3304570b0), [`38f8a79625838a9cd4520b20c0db2e5d331f7d26`](https://github.com/Shopify/hydrogen/commit/38f8a79625838a9cd4520b20c0db2e5d331f7d26)]:
228
+ - @shopify/hydrogen@2026.0.0
229
+
230
+ ## 2025.7.3
231
+
232
+ ### Patch Changes
233
+
234
+ - Support OAuth parameters via URL query strings in skeleton login route ([#3391](https://github.com/Shopify/hydrogen/pull/3391)) by [@kdaviduik](https://github.com/kdaviduik)
235
+
236
+ The skeleton template's login route (`account_.login.tsx`) now reads OAuth parameters from the URL and forwards them to `customerAccount.login()`. This enables deep linking to the login page with pre-configured authentication options.
237
+
238
+ ### Supported Query Parameters
239
+
240
+ | Query Parameter | Description |
241
+ | ----------------- | ---------------------------------------------------------------------------------- |
242
+ | `acr_values` | Direct users to a specific login method (e.g., `provider:google` for social login) |
243
+ | `login_hint` | Pre-fill the email address field |
244
+ | `login_hint_mode` | When set to `submit` with `login_hint`, auto-submits the login form |
245
+ | `locale` | Display the login page in a specific language (e.g., `fr`, `zh-CN`) |
246
+
247
+ ### Usage Examples
248
+
249
+ ```
250
+ /account/login?login_hint=user@example.com
251
+ /account/login?login_hint=user@example.com&login_hint_mode=submit
252
+ /account/login?acr_values=provider:google
253
+ /account/login?locale=fr
254
+ ```
255
+
256
+ - Updated dependencies [[`7c077f5f21a595c0355873ac8073b716dfeaf4d0`](https://github.com/Shopify/hydrogen/commit/7c077f5f21a595c0355873ac8073b716dfeaf4d0), [`7c077f5f21a595c0355873ac8073b716dfeaf4d0`](https://github.com/Shopify/hydrogen/commit/7c077f5f21a595c0355873ac8073b716dfeaf4d0), [`7c077f5f21a595c0355873ac8073b716dfeaf4d0`](https://github.com/Shopify/hydrogen/commit/7c077f5f21a595c0355873ac8073b716dfeaf4d0)]:
257
+ - @shopify/hydrogen@2025.8.0
258
+
259
+ ## 2025.7.2
260
+
261
+ ### Patch Changes
262
+
263
+ - Updated dependencies [[`6d22e45d29e89a7a8dddfe3c06459d89e4590483`](https://github.com/Shopify/hydrogen/commit/6d22e45d29e89a7a8dddfe3c06459d89e4590483), [`702f966c8e60eba7434363c9012f12bed92a8e4d`](https://github.com/Shopify/hydrogen/commit/702f966c8e60eba7434363c9012f12bed92a8e4d)]:
264
+ - @shopify/hydrogen@2025.7.2
265
+
266
+ ## 2025.7.1
267
+
268
+ ### Patch Changes
269
+
270
+ - Update React Router to 7.12.0 with stabilized future flags ([#3346](https://github.com/Shopify/hydrogen/pull/3346)) by [@kdaviduik](https://github.com/kdaviduik)
271
+
272
+ This release uses React Router's newly stabilized future flags (`v8_splitRouteModules`, `v8_middleware`) instead of their unstable counterparts
273
+
274
+ - Moved server build in `server.ts` from a dynamic import to a static import to speed up first rendering during local development (2s => 200ms). ([#3331](https://github.com/Shopify/hydrogen/pull/3331)) by [@frandiox](https://github.com/frandiox)
275
+
276
+ ```diff
277
+ // server.ts
278
+
279
+ +import * as serverBuild from 'virtual:react-router/server-build';
280
+
281
+ const handleRequest = createRequestHandler({
282
+ - build: await import('virtual:react-router/server-build'),
283
+ + build: serverBuild,
284
+ ```
285
+
286
+ Updated ESLint config to allow `virtual:` imports:
287
+
288
+ ```diff
289
+ // eslint.config.js
290
+
291
+ rules: {
292
+ + 'import/no-unresolved': ['error', {ignore: ['^virtual:']}],
293
+ ```
294
+
295
+ - Updated dependencies [[`264e13349168f17cc1f096c84135d13d38cfc8df`](https://github.com/Shopify/hydrogen/commit/264e13349168f17cc1f096c84135d13d38cfc8df), [`6d5e3d371e7e02e15be17029a0f34daae53a978e`](https://github.com/Shopify/hydrogen/commit/6d5e3d371e7e02e15be17029a0f34daae53a978e), [`ee00f1025867c40d5f67fa89d4ffb215bf280e8f`](https://github.com/Shopify/hydrogen/commit/ee00f1025867c40d5f67fa89d4ffb215bf280e8f), [`5a38948133766e358c5f357f52562f6fdcfe7969`](https://github.com/Shopify/hydrogen/commit/5a38948133766e358c5f357f52562f6fdcfe7969), [`264e13349168f17cc1f096c84135d13d38cfc8df`](https://github.com/Shopify/hydrogen/commit/264e13349168f17cc1f096c84135d13d38cfc8df)]:
296
+ - @shopify/hydrogen@2025.7.1
297
+
298
+ ## 2025.7.0
299
+
300
+ ### Major Changes
301
+
302
+ - 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)
303
+
304
+ This update includes:
305
+ - Updated API version constants to 2025-07
306
+ - Regenerated GraphQL types for both Storefront and Customer Account APIs
307
+ - Updated all hardcoded API version references in documentation and tests
308
+ - Regenerated skeleton template types
309
+ - Updated skeleton's @shopify/cli dependency to ~3.83.3
310
+
311
+ Breaking changes may occur due to API schema changes between versions.
312
+
313
+ ### Patch Changes
314
+
315
+ - Fix defer/streaming in development & preview ([#3039](https://github.com/Shopify/hydrogen/pull/3039)) by [@kdaviduik](https://github.com/kdaviduik)
316
+
317
+ - Upgrade Miniflare from v2 to v4 in mini-oxygen package. ([#3039](https://github.com/Shopify/hydrogen/pull/3039)) by [@kdaviduik](https://github.com/kdaviduik)
318
+ - Internal MiniOxygen API has been refactored to work with Miniflare v4's new architecture.
319
+ - Simplified MiniOxygen class - no longer extends MiniflareCore.
320
+ - Updated global fetch handling to use Miniflare v4's `outboundService` API.
321
+ - Fixed test infrastructure to use project-relative temporary directories.
322
+ - Added support for Oxygen compatibility parameters (`compatibilityDate`, `compatibilityFlags`).
323
+ - Removed dependency on multiple `@miniflare/*` packages in favor of the consolidated `miniflare` package.
324
+
325
+ - 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)
326
+
327
+ - 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)
328
+
329
+ 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).
330
+
331
+ - 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)
332
+
333
+ #### Changes for Existing Projects
334
+
335
+ 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:
336
+
337
+ ```diff
338
+ // app/entry.client.tsx
339
+ import {HydratedRouter} from 'react-router/dom';
340
+ import {startTransition, StrictMode} from 'react';
341
+ import {hydrateRoot} from 'react-dom/client';
342
+ + import {NonceProvider} from '@shopify/hydrogen';
343
+
344
+ if (!window.location.origin.includes('webcache.googleusercontent.com')) {
345
+ startTransition(() => {
346
+ + // Extract nonce from existing script tags
347
+ + const existingNonce = document
348
+ + .querySelector<HTMLScriptElement>('script[nonce]')
349
+ + ?.nonce;
350
+ +
351
+ hydrateRoot(
352
+ document,
353
+ <StrictMode>
354
+ - <HydratedRouter />
355
+ + <NonceProvider value={existingNonce}>
356
+ + <HydratedRouter />
357
+ + </NonceProvider>
358
+ </StrictMode>,
359
+ );
360
+ });
361
+ }
362
+ ```
363
+
364
+ This ensures the React Context tree matches between server and client rendering, preventing hydration mismatches.
365
+
366
+ #### Package Changes
367
+ - **@shopify/hydrogen**: Exported `NonceProvider` from the main package to allow client-side usage and simplified Vite configuration to improve React Context stability during development
368
+ - **skeleton**: Updated the template's `entry.client.tsx` to include the `NonceProvider` wrapper during hydration
369
+
370
+ - Add `fulfillmentStatus` to CAAPI order query and route ([#3039](https://github.com/Shopify/hydrogen/pull/3039)) by [@kdaviduik](https://github.com/kdaviduik)
371
+
372
+ - Add GraphQL @defer directive support to storefront client ([#3039](https://github.com/Shopify/hydrogen/pull/3039)) by [@kdaviduik](https://github.com/kdaviduik)
373
+
374
+ - 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)
375
+
376
+ - Add `@inContext` language support to Customer Account API mutations ([#3039](https://github.com/Shopify/hydrogen/pull/3039)) by [@kdaviduik](https://github.com/kdaviduik)
377
+
378
+ - 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)
379
+
380
+ - 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)]:
381
+ - @shopify/hydrogen@2026.0.0
382
+
383
+ ## 2025.5.2
384
+
385
+ ### Patch Changes
386
+
387
+ - Fixing the skeleton's Vite Config ([#2958](https://github.com/Shopify/hydrogen/pull/2958)) by [@balazsbajorics](https://github.com/balazsbajorics)
388
+
389
+ ## 2025.5.1
390
+
391
+ ### Patch Changes
392
+
393
+ - Bumping the cli to 3.80.4 ([#2956](https://github.com/Shopify/hydrogen/pull/2956)) by [@balazsbajorics](https://github.com/balazsbajorics)
394
+
395
+ ## 2025.5.0
396
+
397
+ ### Patch Changes
398
+
399
+ - Migrating to React Router 7 ([#2866](https://github.com/Shopify/hydrogen/pull/2866)) by [@balazsbajorics](https://github.com/balazsbajorics)
400
+
401
+ - Updated dependencies [[`e9132d88`](https://github.com/Shopify/hydrogen/commit/e9132d8888ad090d3db41fe4d5d63569a30e9d8e), [`e9132d88`](https://github.com/Shopify/hydrogen/commit/e9132d8888ad090d3db41fe4d5d63569a30e9d8e)]:
402
+ - @shopify/remix-oxygen@3.0.0
403
+ - @shopify/hydrogen@2025.5.0
404
+
405
+ ## 2025.4.0
406
+
407
+ ### Patch Changes
408
+
409
+ - Moved the Cursor rules into more generic LLM prompt files. If you were using the Cursor rules, you will find the prompts in the `cookbook/llms` folder and they can be put into your `.cursor/rules` folder manually. LLM prompt files will be maintained moving forward, while previous Cursor rules will not be updated anymore. ([#2936](https://github.com/Shopify/hydrogen/pull/2936)) by [@ruggishop](https://github.com/ruggishop)
410
+
411
+ - Bump skeleton @shopify/cli and @shopify/mini-oxygen ([#2883](https://github.com/Shopify/hydrogen/pull/2883)) by [@juanpprieto](https://github.com/juanpprieto)
412
+
413
+ - Update SFAPI and CAAPI versions to 2025.04 ([#2886](https://github.com/Shopify/hydrogen/pull/2886)) by [@juanpprieto](https://github.com/juanpprieto)
414
+
415
+ - Updated dependencies [[`af23e710`](https://github.com/Shopify/hydrogen/commit/af23e710dac83bb57498d9c2ef1d8bcf9df55d34), [`9d8a6644`](https://github.com/Shopify/hydrogen/commit/9d8a6644a5b67dca890c6687df390aee78fc85c3)]:
416
+ - @shopify/hydrogen@2025.4.0
417
+
418
+ ## 2025.1.7
419
+
420
+ ### Patch Changes
421
+
422
+ - 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)
423
+ 1. https://hydrogen.shop/de-de/products/das-chaos
424
+ 2. https://hydrogen.shop/de-de/products/the-havoc
425
+
426
+ We've changed the starter template to make the second redirect to the first.
427
+
428
+ - Added the Cursor rule for the subscriptions recipe. ([#2874](https://github.com/Shopify/hydrogen/pull/2874)) by [@ruggishop](https://github.com/ruggishop)
429
+
430
+ - Fix faulty truthiness check for cart quantity ([#2855](https://github.com/Shopify/hydrogen/pull/2855)) by [@frontsideair](https://github.com/frontsideair)
431
+
432
+ - Refactor ProductItem into a separate component ([#2872](https://github.com/Shopify/hydrogen/pull/2872)) by [@juanpprieto](https://github.com/juanpprieto)
433
+
434
+ - Updated dependencies [[`f80f3bc7`](https://github.com/Shopify/hydrogen/commit/f80f3bc7239b3ee6641cb468a17e15c77bb7815b), [`61ddf924`](https://github.com/Shopify/hydrogen/commit/61ddf92487524b3c04632ae2cfdaa2869a3ae02c), [`642bde4f`](https://github.com/Shopify/hydrogen/commit/642bde4f3df11511e125b013abd977618da25692)]:
435
+ - @shopify/hydrogen@2025.1.4
436
+
437
+ ## 2025.1.6
438
+
439
+ ### Patch Changes
440
+
441
+ - 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)
442
+ 1. If you have a separate `app/layout.tsx` file, delete it and move its default exported component into your `root.tsx`. For example:
443
+
444
+ ```ts
445
+ // /app/root.tsx
446
+ export function Layout({children}: {children?: React.ReactNode}) {
447
+ const nonce = useNonce();
448
+ const data = useRouteLoaderData<RootLoader>('root');
449
+
450
+ return (
451
+ <html lang="en">
452
+ ...
453
+ );
454
+ }
455
+ ```
456
+
457
+ ## 2025.1.5
458
+
459
+ ### Patch Changes
460
+
461
+ - Fixed an issue with the creation of JavaScript projects. ([#2818](https://github.com/Shopify/hydrogen/pull/2818)) by [@seanparsons](https://github.com/seanparsons)
462
+
463
+ ## 2025.1.4
464
+
465
+ ### Patch Changes
466
+
467
+ - Updates the `@shopify/cli`, `@shopify/cli-kit` and `@shopify/plugin-cloudflare` dependencies to 3.77.1. ([#2816](https://github.com/Shopify/hydrogen/pull/2816)) by [@seanparsons](https://github.com/seanparsons)
468
+
469
+ ## 2025.1.3
470
+
471
+ ### Patch Changes
472
+
473
+ - Bump Remix to 2.16.1 and vite to 6.2.0 ([#2784](https://github.com/Shopify/hydrogen/pull/2784)) by [@wizardlyhel](https://github.com/wizardlyhel)
474
+
475
+ - Update skeleton and create-hydrogen cli to 3.75.4 ([#2769](https://github.com/Shopify/hydrogen/pull/2769)) by [@juanpprieto](https://github.com/juanpprieto)
476
+
477
+ - Fixing typescript compile ([#2787](https://github.com/Shopify/hydrogen/pull/2787)) by [@balazsbajorics](https://github.com/balazsbajorics)
478
+
479
+ In tsconfig.json:
480
+
481
+ ```diff
482
+ "types": [
483
+ "@shopify/oxygen-workers-types",
484
+ - "@remix-run/node",
485
+ + "@remix-run/server-runtime",
486
+ "vite/client"
487
+ ],
488
+ ```
489
+
490
+ - Updates `@shopify/cli-kit`, `@shopify/cli` and `@shopify/plugin-cloudflare` to `3.77.0`. ([#2810](https://github.com/Shopify/hydrogen/pull/2810)) by [@seanparsons](https://github.com/seanparsons)
491
+
492
+ - Support for the Remix future flag `v3_routeConfig`. ([#2722](https://github.com/Shopify/hydrogen/pull/2722)) by [@seanparsons](https://github.com/seanparsons)
493
+
494
+ 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)
495
+ 1. Update your `vite.config.ts`.
496
+
497
+ ```diff
498
+ export default defineConfig({
499
+ plugins: [
500
+ hydrogen(),
501
+ oxygen(),
502
+ remix({
503
+ - presets: [hydrogen.preset()],
504
+ + presets: [hydrogen.v3preset()],
505
+ future: {
506
+ v3_fetcherPersist: true,
507
+ v3_relativeSplatPath: true,
508
+ v3_throwAbortReason: true,
509
+ v3_lazyRouteDiscovery: true,
510
+ v3_singleFetch: true,
511
+ + v3_routeConfig: true,
512
+ },
513
+ }),
514
+ tsconfigPaths(),
515
+ ],
516
+ ```
517
+
518
+ 1. Update your `package.json` and install the new packages. Make sure to match the Remix version along with other Remix npm packages and ensure the versions are 2.16.1 or above:
519
+
520
+ ```diff
521
+ "devDependencies": {
522
+ "@remix-run/dev": "^2.16.1",
523
+ + "@remix-run/fs-routes": "^2.16.1",
524
+ + "@remix-run/route-config": "^2.16.1",
525
+ ```
526
+
527
+ 1. Move the `Layout` component export from `root.tsx` into its own file. Make sure to supply an `<Outlet>` so Remix knows where to inject your route content.
528
+
529
+ ```ts
530
+ // /app/layout.tsx
531
+ import {Outlet} from '@remix-run/react';
532
+
533
+ export default function Layout() {
534
+ const nonce = useNonce();
535
+ const data = useRouteLoaderData<RootLoader>('root');
536
+
537
+ return (
538
+ <html lang="en">
539
+ ...
540
+ <Outlet />
541
+ ...
542
+ </html>
543
+ );
544
+ }
545
+
546
+ // Remember to remove the Layout export from your root.tsx
547
+ ```
548
+
549
+ 1. Add a routes.ts file. This is your new Remix route configuration file.
550
+
551
+ ```ts
552
+ import {flatRoutes} from '@remix-run/fs-routes';
553
+ import {layout, type RouteConfig} from '@remix-run/route-config';
554
+ import {hydrogenRoutes} from '@shopify/hydrogen';
555
+
556
+ export default hydrogenRoutes([
557
+ // Your entire app reading from routes folder using Layout from layout.tsx
558
+ layout('./layout.tsx', await flatRoutes()),
559
+ ]) satisfies RouteConfig;
560
+ ```
561
+
562
+ - Updated dependencies [[`0425e50d`](https://github.com/Shopify/hydrogen/commit/0425e50dafe2f42326cba67076e5fcea2905e885), [`74ef1ba7`](https://github.com/Shopify/hydrogen/commit/74ef1ba7d41988350e9d2c81731c90381943d1f0)]:
563
+ - @shopify/remix-oxygen@2.0.12
564
+ - @shopify/hydrogen@2025.1.3
565
+
566
+ ## 2025.1.2
567
+
568
+ ### Patch Changes
569
+
570
+ - Bump cli version ([#2760](https://github.com/Shopify/hydrogen/pull/2760)) by [@rbshop](https://github.com/rbshop)
571
+
572
+ - Updated dependencies [[`128dfcd6`](https://github.com/Shopify/hydrogen/commit/128dfcd6b254a7465d93be49d3bcbff5251e5ffc)]:
573
+ - @shopify/hydrogen@2025.1.2
574
+
575
+ ## 2025.1.1
576
+
577
+ ### Patch Changes
578
+
579
+ - 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)
580
+
581
+ - Bump remix version ([#2740](https://github.com/Shopify/hydrogen/pull/2740)) by [@wizardlyhel](https://github.com/wizardlyhel)
582
+
583
+ - Turn on Remix `v3_singleFetch` future flag ([#2708](https://github.com/Shopify/hydrogen/pull/2708)) by [@wizardlyhel](https://github.com/wizardlyhel)
584
+
585
+ Remix single fetch migration quick guide: https://remix.run/docs/en/main/start/future-flags#v3_singlefetch
586
+ Remix single fetch migration guide: https://remix.run/docs/en/main/guides/single-fetch
587
+
588
+ **Note:** If you have any routes that appends (or looks for) a search param named `_data`, make sure to rename it to something else.
589
+ 1. In your `vite.config.ts`, add the single fetch future flag.
590
+
591
+ ```diff
592
+ + declare module "@remix-run/server-runtime" {
593
+ + interface Future {
594
+ + v3_singleFetch: true;
595
+ + }
596
+ + }
597
+
598
+ export default defineConfig({
599
+ plugins: [
600
+ hydrogen(),
601
+ oxygen(),
602
+ remix({
603
+ presets: [hydrogen.preset()],
604
+ future: {
605
+ v3_fetcherPersist: true,
606
+ v3_relativeSplatPath: true,
607
+ v3_throwAbortReason: true,
608
+ v3_lazyRouteDiscovery: true,
609
+ + v3_singleFetch: true,
610
+ },
611
+ }),
612
+ tsconfigPaths(),
613
+ ],
614
+ ```
615
+
616
+ 2. In your `entry.server.tsx`, add `nonce` to the `<RemixServer>`.
617
+
618
+ ```diff
619
+ const body = await renderToReadableStream(
620
+ <NonceProvider>
621
+ <RemixServer
622
+ context={remixContext}
623
+ url={request.url}
624
+ + nonce={nonce}
625
+ />
626
+ </NonceProvider>,
627
+ ```
628
+
629
+ 3. Update the `shouldRevalidate` function in `root.tsx`.
630
+
631
+ 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.
632
+
633
+ For more details see: https://remix.run/docs/en/main/route/should-revalidate
634
+
635
+ ```diff
636
+ export const shouldRevalidate: ShouldRevalidateFunction = ({
637
+ formMethod,
638
+ currentUrl,
639
+ nextUrl,
640
+ - defaultShouldRevalidate,
641
+ }) => {
642
+ // revalidate when a mutation is performed e.g add to cart, login...
643
+ if (formMethod && formMethod !== 'GET') return true;
644
+
645
+ // revalidate when manually revalidating via useRevalidator
646
+ if (currentUrl.toString() === nextUrl.toString()) return true;
647
+
648
+ - return defaultShouldRevalidate;
649
+ + return false;
650
+ };
651
+ ```
652
+
653
+ 4. Update `cart.tsx` to add a headers export and update to `data` import usage.
654
+
655
+ ```diff
656
+ import {
657
+ - json,
658
+ + data,
659
+ type LoaderFunctionArgs,
660
+ type ActionFunctionArgs,
661
+ type HeadersFunction
662
+ } from '@shopify/remix-oxygen';
663
+ + export const headers: HeadersFunction = ({actionHeaders}) => actionHeaders;
664
+
665
+ export async function action({request, context}: ActionFunctionArgs) {
666
+ ...
667
+ - return json(
668
+ + return data(
669
+ {
670
+ cart: cartResult,
671
+ errors,
672
+ warnings,
673
+ analytics: {
674
+ cartId,
675
+ },
676
+ },
677
+ {status, headers},
678
+ );
679
+ }
680
+
681
+ export async function loader({context}: LoaderFunctionArgs) {
682
+ const {cart} = context;
683
+ - return json(await cart.get());
684
+ + return await cart.get();
685
+ }
686
+ ```
687
+
688
+ 5. Deprecate `json` and `defer` import usage from `@shopify/remix-oxygen`.
689
+
690
+ Remove `json()`/`defer()` in favor of raw objects.
691
+
692
+ Single Fetch supports JSON objects and Promises out of the box, so you can return the raw data from your loader/action functions:
693
+
694
+ ```diff
695
+ - import {json} from "@shopify/remix-oxygen";
696
+
697
+ export async function loader({}: LoaderFunctionArgs) {
698
+ let tasks = await fetchTasks();
699
+ - return json(tasks);
700
+ + return tasks;
701
+ }
702
+ ```
703
+
704
+ ```diff
705
+ - import {defer} from "@shopify/remix-oxygen";
706
+
707
+ export async function loader({}: LoaderFunctionArgs) {
708
+ let lazyStuff = fetchLazyStuff();
709
+ let tasks = await fetchTasks();
710
+ - return defer({ tasks, lazyStuff });
711
+ + return { tasks, lazyStuff };
712
+ }
713
+ ```
714
+
715
+ 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:
716
+
717
+ ```diff
718
+ - import {json} from "@shopify/remix-oxygen";
719
+ + import {data, type HeadersFunction} from "@shopify/remix-oxygen";
720
+
721
+ + /**
722
+ + * If your loader or action is returning a response with headers,
723
+ + * make sure to export a headers function that merges your headers
724
+ + * on your route. Otherwise, your headers may be lost.
725
+ + * Remix doc: https://remix.run/docs/en/main/route/headers
726
+ + **/
727
+ + export const headers: HeadersFunction = ({loaderHeaders}) => loaderHeaders;
728
+
729
+ export async function loader({}: LoaderFunctionArgs) {
730
+ let tasks = await fetchTasks();
731
+ - return json(tasks, {
732
+ + return data(tasks, {
733
+ headers: {
734
+ "Cache-Control": "public, max-age=604800"
735
+ }
736
+ });
737
+ }
738
+ ```
739
+
740
+ 6. If you are using legacy customer account flow or multipass, there are a couple more files that requires updating:
741
+
742
+ In `root.tsx` and `routes/account.tsx`, add a `headers` export for `loaderHeaders`.
743
+
744
+ ```diff
745
+ + export const headers: HeadersFunction = ({loaderHeaders}) => loaderHeaders;
746
+ ```
747
+
748
+ In `routes/account_.register.tsx`, add a `headers` export for `actionHeaders`.
749
+
750
+ ```diff
751
+ + export const headers: HeadersFunction = ({actionHeaders}) => actionHeaders;
752
+ ```
753
+
754
+ 7. If you are using multipass, in `routes/account_.login.multipass.tsx`
755
+
756
+ a. export a `headers` export
757
+
758
+ ```diff
759
+ + export const headers: HeadersFunction = ({actionHeaders}) => actionHeaders;
760
+ ```
761
+
762
+ b. Update all `json` response wrapper to `remixData`
763
+
764
+ ```diff
765
+ import {
766
+ - json,
767
+ + data as remixData,
768
+ } from '@shopify/remix-oxygen';
769
+
770
+ - return json(
771
+ + return remixData(
772
+ ...
773
+ );
774
+ ```
775
+
776
+ - 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)]:
777
+ - @shopify/hydrogen@2025.1.1
778
+ - @shopify/remix-oxygen@2.0.11
779
+
780
+ ## 2025.1.0
781
+
782
+ ### Patch Changes
783
+
784
+ - Bump vite, Remix versions and tailwind v4 alpha to beta ([#2696](https://github.com/Shopify/hydrogen/pull/2696)) by [@wizardlyhel](https://github.com/wizardlyhel)
785
+
786
+ - Workaround for "Error: failed to execute 'insertBefore' on 'Node'" that sometimes happen during development. ([#2701](https://github.com/Shopify/hydrogen/pull/2701)) by [@wizardlyhel](https://github.com/wizardlyhel)
787
+
788
+ ```diff
789
+ // root.tsx
790
+
791
+ /**
792
+ * The main and reset stylesheets are added in the Layout component
793
+ * to prevent a bug in development HMR updates.
794
+ *
795
+ * This avoids the "failed to execute 'insertBefore' on 'Node'" error
796
+ * that occurs after editing and navigating to another page.
797
+ *
798
+ * It's a temporary fix until the issue is resolved.
799
+ * https://github.com/remix-run/remix/issues/9242
800
+ */
801
+ export function links() {
802
+ return [
803
+ - {rel: 'stylesheet', href: resetStyles},
804
+ - {rel: 'stylesheet', href: appStyles},
805
+ {
806
+ rel: 'preconnect',
807
+ href: 'https://cdn.shopify.com',
808
+ },
809
+ {
810
+ rel: 'preconnect',
811
+ href: 'https://shop.app',
812
+ },
813
+ {rel: 'icon', type: 'image/svg+xml', href: favicon},
814
+ ];
815
+ }
816
+
817
+ ...
818
+
819
+ export function Layout({children}: {children?: React.ReactNode}) {
820
+ const nonce = useNonce();
821
+ const data = useRouteLoaderData<RootLoader>('root');
822
+
823
+ return (
824
+ <html lang="en">
825
+ <head>
826
+ <meta charSet="utf-8" />
827
+ <meta name="viewport" content="width=device-width,initial-scale=1" />
828
+ + <link rel="stylesheet" href={resetStyles}></link>
829
+ + <link rel="stylesheet" href={appStyles}></link>
830
+
831
+ ```
832
+
833
+ - Turn on future flag `v3_lazyRouteDiscovery` ([#2702](https://github.com/Shopify/hydrogen/pull/2702)) by [@wizardlyhel](https://github.com/wizardlyhel)
834
+
835
+ In your vite.config.ts, add the following line:
836
+
837
+ ```diff
838
+ export default defineConfig({
839
+ plugins: [
840
+ hydrogen(),
841
+ oxygen(),
842
+ remix({
843
+ presets: [hydrogen.preset()],
844
+ future: {
845
+ v3_fetcherPersist: true,
846
+ v3_relativeSplatPath: true,
847
+ v3_throwAbortReason: true,
848
+ + v3_lazyRouteDiscovery: true,
849
+ },
850
+ }),
851
+ tsconfigPaths(),
852
+ ],
853
+ ```
854
+
855
+ Test your app by running `npm run dev` and nothing should break
856
+
857
+ - Fix image size warnings on collections page ([#2703](https://github.com/Shopify/hydrogen/pull/2703)) by [@wizardlyhel](https://github.com/wizardlyhel)
858
+
859
+ - Bump cli version ([#2732](https://github.com/Shopify/hydrogen/pull/2732)) by [@wizardlyhel](https://github.com/wizardlyhel)
860
+
861
+ - Bump SFAPI to 2025-01 ([#2715](https://github.com/Shopify/hydrogen/pull/2715)) by [@rbshop](https://github.com/rbshop)
862
+
863
+ - Updated dependencies [[`fdab06f5`](https://github.com/Shopify/hydrogen/commit/fdab06f5d34076b526d406698bdf6fca6787660b), [`ae6d71f0`](https://github.com/Shopify/hydrogen/commit/ae6d71f0976f520ca177c69ff677f852af63859e), [`650d57b3`](https://github.com/Shopify/hydrogen/commit/650d57b3e07125661e23900e73c0bb3027ddbcde), [`064de138`](https://github.com/Shopify/hydrogen/commit/064de13890c68cabb1c3fdbe7f77409a0cf1c384)]:
864
+ - @shopify/remix-oxygen@2.0.10
865
+ - @shopify/hydrogen@2025.1.0
866
+
867
+ ## 2024.10.4
868
+
869
+ ### Patch Changes
870
+
871
+ - Bump cli version ([#2694](https://github.com/Shopify/hydrogen/pull/2694)) by [@wizardlyhel](https://github.com/wizardlyhel)
872
+
873
+ ## 2024.10.3
874
+
875
+ ### Patch Changes
876
+
877
+ - Prevent scroll reset on variant change ([#2672](https://github.com/Shopify/hydrogen/pull/2672)) by [@scottdixon](https://github.com/scottdixon)
878
+
879
+ ## 2024.10.2
880
+
881
+ ### Patch Changes
882
+
883
+ - Remove initial redirect from product display page ([#2643](https://github.com/Shopify/hydrogen/pull/2643)) by [@scottdixon](https://github.com/scottdixon)
884
+
885
+ - 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)
886
+ 1. Update your SFAPI product query to bring in the new query fields:
887
+
888
+ ```diff
889
+ const PRODUCT_FRAGMENT = `#graphql
890
+ fragment Product on Product {
891
+ id
892
+ title
893
+ vendor
894
+ handle
895
+ descriptionHtml
896
+ description
897
+ + encodedVariantExistence
898
+ + encodedVariantAvailability
899
+ options {
900
+ name
901
+ optionValues {
902
+ name
903
+ + firstSelectableVariant {
904
+ + ...ProductVariant
905
+ + }
906
+ + swatch {
907
+ + color
908
+ + image {
909
+ + previewImage {
910
+ + url
911
+ + }
912
+ + }
913
+ + }
914
+ }
915
+ }
916
+ - selectedVariant: selectedOrFirstAvailableVariant(selectedOptions: $selectedOptions, ignoreUnknownOptions: true, caseInsensitiveMatch: true) {
917
+ + selectedOrFirstAvailableVariant(selectedOptions: $selectedOptions, ignoreUnknownOptions: true, caseInsensitiveMatch: true) {
918
+ + ...ProductVariant
919
+ + }
920
+ + adjacentVariants (selectedOptions: $selectedOptions) {
921
+ + ...ProductVariant
922
+ + }
923
+ - variants(first: 1) {
924
+ - nodes {
925
+ - ...ProductVariant
926
+ - }
927
+ - }
928
+ seo {
929
+ description
930
+ title
931
+ }
932
+ }
933
+ ${PRODUCT_VARIANT_FRAGMENT}
934
+ ` as const;
935
+ ```
936
+
937
+ 2. Update `loadDeferredData` function. We no longer need to load in all the variants. You can also remove `VARIANTS_QUERY` variable.
938
+
939
+ ```diff
940
+ function loadDeferredData({context, params}: LoaderFunctionArgs) {
941
+ + // Put any API calls that is not critical to be available on first page render
942
+ + // For example: product reviews, product recommendations, social feeds.
943
+ - // In order to show which variants are available in the UI, we need to query
944
+ - // all of them. But there might be a *lot*, so instead separate the variants
945
+ - // into it's own separate query that is deferred. So there's a brief moment
946
+ - // where variant options might show as available when they're not, but after
947
+ - // this deferred query resolves, the UI will update.
948
+ - const variants = context.storefront
949
+ - .query(VARIANTS_QUERY, {
950
+ - variables: {handle: params.handle!},
951
+ - })
952
+ - .catch((error) => {
953
+ - // Log query errors, but don't throw them so the page can still render
954
+ - console.error(error);
955
+ - return null;
956
+ - });
957
+
958
+ + return {}
959
+ - return {
960
+ - variants,
961
+ - };
962
+ }
963
+ ```
964
+
965
+ 3. Remove the redirect logic in the `loadCriticalData` function and completely remove `redirectToFirstVariant` function
966
+
967
+ ```diff
968
+ async function loadCriticalData({
969
+ context,
970
+ params,
971
+ request,
972
+ }: LoaderFunctionArgs) {
973
+ const {handle} = params;
974
+ const {storefront} = context;
975
+ if (!handle) {
976
+ throw new Error('Expected product handle to be defined');
977
+ }
978
+ const [{product}] = await Promise.all([
979
+ storefront.query(PRODUCT_QUERY, {
980
+ variables: {handle, selectedOptions: getSelectedProductOptions(request)},
981
+ }),
982
+ // Add other queries here, so that they are loaded in parallel
983
+ ]);
984
+
985
+ if (!product?.id) {
986
+ throw new Response(null, {status: 404});
987
+ }
988
+
989
+ - const firstVariant = product.variants.nodes[0];
990
+ - const firstVariantIsDefault = Boolean(
991
+ - firstVariant.selectedOptions.find(
992
+ - (option: SelectedOption) =>
993
+ - option.name === 'Title' && option.value === 'Default Title',
994
+ - ),
995
+ - );
996
+
997
+ - if (firstVariantIsDefault) {
998
+ - product.selectedVariant = firstVariant;
999
+ - } else {
1000
+ - // if no selected variant was returned from the selected options,
1001
+ - // we redirect to the first variant's url with it's selected options applied
1002
+ - if (!product.selectedVariant) {
1003
+ - throw redirectToFirstVariant({product, request});
1004
+ - }
1005
+ - }
1006
+
1007
+ return {
1008
+ product,
1009
+ };
1010
+ }
1011
+
1012
+ ...
1013
+
1014
+ - function redirectToFirstVariant({
1015
+ - product,
1016
+ - request,
1017
+ - }: {
1018
+ - product: ProductFragment;
1019
+ - request: Request;
1020
+ - }) {
1021
+ - ...
1022
+ - }
1023
+ ```
1024
+
1025
+ 4. Update the `Product` component to use the new data fields.
1026
+
1027
+ ```diff
1028
+ import {
1029
+ getSelectedProductOptions,
1030
+ Analytics,
1031
+ useOptimisticVariant,
1032
+ + getAdjacentAndFirstAvailableVariants,
1033
+ } from '@shopify/hydrogen';
1034
+
1035
+ export default function Product() {
1036
+ + const {product} = useLoaderData<typeof loader>();
1037
+ - const {product, variants} = useLoaderData<typeof loader>();
1038
+
1039
+ + // Optimistically selects a variant with given available variant information
1040
+ + const selectedVariant = useOptimisticVariant(
1041
+ + product.selectedOrFirstAvailableVariant,
1042
+ + getAdjacentAndFirstAvailableVariants(product),
1043
+ + );
1044
+ - const selectedVariant = useOptimisticVariant(
1045
+ - product.selectedVariant,
1046
+ - variants,
1047
+ - );
1048
+ ```
1049
+
1050
+ 5. Handle missing search query param in url from selecting a first variant
1051
+
1052
+ ```diff
1053
+ import {
1054
+ getSelectedProductOptions,
1055
+ Analytics,
1056
+ useOptimisticVariant,
1057
+ getAdjacentAndFirstAvailableVariants,
1058
+ + useSelectedOptionInUrlParam,
1059
+ } from '@shopify/hydrogen';
1060
+
1061
+ export default function Product() {
1062
+ const {product} = useLoaderData<typeof loader>();
1063
+
1064
+ // Optimistically selects a variant with given available variant information
1065
+ const selectedVariant = useOptimisticVariant(
1066
+ product.selectedOrFirstAvailableVariant,
1067
+ getAdjacentAndFirstAvailableVariants(product),
1068
+ );
1069
+
1070
+ + // Sets the search param to the selected variant without navigation
1071
+ + // only when no search params are set in the url
1072
+ + useSelectedOptionInUrlParam(selectedVariant.selectedOptions);
1073
+ ```
1074
+
1075
+ 6. Get the product options array using `getProductOptions`
1076
+
1077
+ ```diff
1078
+ import {
1079
+ getSelectedProductOptions,
1080
+ Analytics,
1081
+ useOptimisticVariant,
1082
+ + getProductOptions,
1083
+ getAdjacentAndFirstAvailableVariants,
1084
+ useSelectedOptionInUrlParam,
1085
+ } from '@shopify/hydrogen';
1086
+
1087
+ export default function Product() {
1088
+ const {product} = useLoaderData<typeof loader>();
1089
+
1090
+ // Optimistically selects a variant with given available variant information
1091
+ const selectedVariant = useOptimisticVariant(
1092
+ product.selectedOrFirstAvailableVariant,
1093
+ getAdjacentAndFirstAvailableVariants(product),
1094
+ );
1095
+
1096
+ // Sets the search param to the selected variant without navigation
1097
+ // only when no search params are set in the url
1098
+ useSelectedOptionInUrlParam(selectedVariant.selectedOptions);
1099
+
1100
+ + // Get the product options array
1101
+ + const productOptions = getProductOptions({
1102
+ + ...product,
1103
+ + selectedOrFirstAvailableVariant: selectedVariant,
1104
+ + });
1105
+ ```
1106
+
1107
+ 7. Remove the `Await` and `Suspense` from the `ProductForm`. We no longer have any queries that we need to wait for.
1108
+
1109
+ ```diff
1110
+ export default function Product() {
1111
+
1112
+ ...
1113
+
1114
+ return (
1115
+ ...
1116
+ + <ProductForm
1117
+ + productOptions={productOptions}
1118
+ + selectedVariant={selectedVariant}
1119
+ + />
1120
+ - <Suspense
1121
+ - fallback={
1122
+ - <ProductForm
1123
+ - product={product}
1124
+ - selectedVariant={selectedVariant}
1125
+ - variants={[]}
1126
+ - />
1127
+ - }
1128
+ - >
1129
+ - <Await
1130
+ - errorElement="There was a problem loading product variants"
1131
+ - resolve={variants}
1132
+ - >
1133
+ - {(data) => (
1134
+ - <ProductForm
1135
+ - product={product}
1136
+ - selectedVariant={selectedVariant}
1137
+ - variants={data?.product?.variants.nodes || []}
1138
+ - />
1139
+ - )}
1140
+ - </Await>
1141
+ - </Suspense>
1142
+ ```
1143
+
1144
+ 8. Update the `ProductForm` component.
1145
+
1146
+ ```tsx
1147
+ import {Link, useNavigate} from '@remix-run/react';
1148
+ import {type MappedProductOptions} from '@shopify/hydrogen';
1149
+ import type {
1150
+ Maybe,
1151
+ ProductOptionValueSwatch,
1152
+ } from '@shopify/hydrogen/storefront-api-types';
1153
+ import {AddToCartButton} from './AddToCartButton';
1154
+ import {useAside} from './Aside';
1155
+ import type {ProductFragment} from 'storefrontapi.generated';
1156
+
1157
+ export function ProductForm({
1158
+ productOptions,
1159
+ selectedVariant,
1160
+ }: {
1161
+ productOptions: MappedProductOptions[];
1162
+ selectedVariant: ProductFragment['selectedOrFirstAvailableVariant'];
1163
+ }) {
1164
+ const navigate = useNavigate();
1165
+ const {open} = useAside();
1166
+ return (
1167
+ <div className="product-form">
1168
+ {productOptions.map((option) => (
1169
+ <div className="product-options" key={option.name}>
1170
+ <h5>{option.name}</h5>
1171
+ <div className="product-options-grid">
1172
+ {option.optionValues.map((value) => {
1173
+ const {
1174
+ name,
1175
+ handle,
1176
+ variantUriQuery,
1177
+ selected,
1178
+ available,
1179
+ exists,
1180
+ isDifferentProduct,
1181
+ swatch,
1182
+ } = value;
1183
+
1184
+ if (isDifferentProduct) {
1185
+ // SEO
1186
+ // When the variant is a combined listing child product
1187
+ // that leads to a different url, we need to render it
1188
+ // as an anchor tag
1189
+ return (
1190
+ <Link
1191
+ className="product-options-item"
1192
+ key={option.name + name}
1193
+ prefetch="intent"
1194
+ preventScrollReset
1195
+ replace
1196
+ to={`/products/${handle}?${variantUriQuery}`}
1197
+ style={{
1198
+ border: selected
1199
+ ? '1px solid black'
1200
+ : '1px solid transparent',
1201
+ opacity: available ? 1 : 0.3,
1202
+ }}
1203
+ >
1204
+ <ProductOptionSwatch swatch={swatch} name={name} />
1205
+ </Link>
1206
+ );
1207
+ } else {
1208
+ // SEO
1209
+ // When the variant is an update to the search param,
1210
+ // render it as a button with javascript navigating to
1211
+ // the variant so that SEO bots do not index these as
1212
+ // duplicated links
1213
+ return (
1214
+ <button
1215
+ type="button"
1216
+ className={`product-options-item${
1217
+ exists && !selected ? ' link' : ''
1218
+ }`}
1219
+ key={option.name + name}
1220
+ style={{
1221
+ border: selected
1222
+ ? '1px solid black'
1223
+ : '1px solid transparent',
1224
+ opacity: available ? 1 : 0.3,
1225
+ }}
1226
+ disabled={!exists}
1227
+ onClick={() => {
1228
+ if (!selected) {
1229
+ navigate(`?${variantUriQuery}`, {
1230
+ replace: true,
1231
+ });
1232
+ }
1233
+ }}
1234
+ >
1235
+ <ProductOptionSwatch swatch={swatch} name={name} />
1236
+ </button>
1237
+ );
1238
+ }
1239
+ })}
1240
+ </div>
1241
+ <br />
1242
+ </div>
1243
+ ))}
1244
+ <AddToCartButton
1245
+ disabled={!selectedVariant || !selectedVariant.availableForSale}
1246
+ onClick={() => {
1247
+ open('cart');
1248
+ }}
1249
+ lines={
1250
+ selectedVariant
1251
+ ? [
1252
+ {
1253
+ merchandiseId: selectedVariant.id,
1254
+ quantity: 1,
1255
+ selectedVariant,
1256
+ },
1257
+ ]
1258
+ : []
1259
+ }
1260
+ >
1261
+ {selectedVariant?.availableForSale ? 'Add to cart' : 'Sold out'}
1262
+ </AddToCartButton>
1263
+ </div>
1264
+ );
1265
+ }
1266
+
1267
+ function ProductOptionSwatch({
1268
+ swatch,
1269
+ name,
1270
+ }: {
1271
+ swatch?: Maybe<ProductOptionValueSwatch> | undefined;
1272
+ name: string;
1273
+ }) {
1274
+ const image = swatch?.image?.previewImage?.url;
1275
+ const color = swatch?.color;
1276
+
1277
+ if (!image && !color) return name;
1278
+
1279
+ return (
1280
+ <div
1281
+ aria-label={name}
1282
+ className="product-option-label-swatch"
1283
+ style={{
1284
+ backgroundColor: color || 'transparent',
1285
+ }}
1286
+ >
1287
+ {!!image && <img src={image} alt={name} />}
1288
+ </div>
1289
+ );
1290
+ }
1291
+ ```
1292
+
1293
+ 9. Update `app.css`
1294
+
1295
+ ```diff
1296
+ + /*
1297
+ + * --------------------------------------------------
1298
+ + * Non anchor links
1299
+ + * --------------------------------------------------
1300
+ + */
1301
+ + .link:hover {
1302
+ + text-decoration: underline;
1303
+ + cursor: pointer;
1304
+ + }
1305
+
1306
+ ...
1307
+
1308
+ - .product-options-item {
1309
+ + .product-options-item,
1310
+ + .product-options-item:disabled {
1311
+ + padding: 0.25rem 0.5rem;
1312
+ + background-color: transparent;
1313
+ + font-size: 1rem;
1314
+ + font-family: inherit;
1315
+ + }
1316
+
1317
+ + .product-option-label-swatch {
1318
+ + width: 1.25rem;
1319
+ + height: 1.25rem;
1320
+ + margin: 0.25rem 0;
1321
+ + }
1322
+
1323
+ + .product-option-label-swatch img {
1324
+ + width: 100%;
1325
+ + }
1326
+ ```
1327
+
1328
+ 10. Update `lib/variants.ts`
1329
+
1330
+ Make `useVariantUrl` and `getVariantUrl` flexible to supplying a selected option param
1331
+
1332
+ ```diff
1333
+ export function useVariantUrl(
1334
+ handle: string,
1335
+ - selectedOptions: SelectedOption[],
1336
+ + selectedOptions?: SelectedOption[],
1337
+ ) {
1338
+ const {pathname} = useLocation();
1339
+
1340
+ return useMemo(() => {
1341
+ return getVariantUrl({
1342
+ handle,
1343
+ pathname,
1344
+ searchParams: new URLSearchParams(),
1345
+ selectedOptions,
1346
+ });
1347
+ }, [handle, selectedOptions, pathname]);
1348
+ }
1349
+ export function getVariantUrl({
1350
+ handle,
1351
+ pathname,
1352
+ searchParams,
1353
+ selectedOptions,
1354
+ }: {
1355
+ handle: string;
1356
+ pathname: string;
1357
+ searchParams: URLSearchParams;
1358
+ - selectedOptions: SelectedOption[];
1359
+ + selectedOptions?: SelectedOption[],
1360
+ }) {
1361
+ const match = /(\/[a-zA-Z]{2}-[a-zA-Z]{2}\/)/g.exec(pathname);
1362
+ const isLocalePathname = match && match.length > 0;
1363
+ const path = isLocalePathname
1364
+ ? `${match![0]}products/${handle}`
1365
+ : `/products/${handle}`;
1366
+
1367
+ - selectedOptions.forEach((option) => {
1368
+ + selectedOptions?.forEach((option) => {
1369
+ searchParams.set(option.name, option.value);
1370
+ });
1371
+ ```
1372
+
1373
+ 11. Update `routes/collections.$handle.tsx`
1374
+
1375
+ We no longer need to query for the variants since product route can efficiently
1376
+ obtain the first available variants. Update the code to reflect that:
1377
+
1378
+ ```diff
1379
+ const PRODUCT_ITEM_FRAGMENT = `#graphql
1380
+ fragment MoneyProductItem on MoneyV2 {
1381
+ amount
1382
+ currencyCode
1383
+ }
1384
+ fragment ProductItem on Product {
1385
+ id
1386
+ handle
1387
+ title
1388
+ featuredImage {
1389
+ id
1390
+ altText
1391
+ url
1392
+ width
1393
+ height
1394
+ }
1395
+ priceRange {
1396
+ minVariantPrice {
1397
+ ...MoneyProductItem
1398
+ }
1399
+ maxVariantPrice {
1400
+ ...MoneyProductItem
1401
+ }
1402
+ }
1403
+ - variants(first: 1) {
1404
+ - nodes {
1405
+ - selectedOptions {
1406
+ - name
1407
+ - value
1408
+ - }
1409
+ - }
1410
+ - }
1411
+ }
1412
+ ` as const;
1413
+ ```
1414
+
1415
+ and remove the variant reference
1416
+
1417
+ ```diff
1418
+ function ProductItem({
1419
+ product,
1420
+ loading,
1421
+ }: {
1422
+ product: ProductItemFragment;
1423
+ loading?: 'eager' | 'lazy';
1424
+ }) {
1425
+ - const variant = product.variants.nodes[0];
1426
+ - const variantUrl = useVariantUrl(product.handle, variant.selectedOptions);
1427
+ + const variantUrl = useVariantUrl(product.handle);
1428
+ return (
1429
+ ```
1430
+
1431
+ 12. Update `routes/collections.all.tsx`
1432
+
1433
+ Same reasoning as `collections.$handle.tsx`
1434
+
1435
+ ```diff
1436
+ const PRODUCT_ITEM_FRAGMENT = `#graphql
1437
+ fragment MoneyProductItem on MoneyV2 {
1438
+ amount
1439
+ currencyCode
1440
+ }
1441
+ fragment ProductItem on Product {
1442
+ id
1443
+ handle
1444
+ title
1445
+ featuredImage {
1446
+ id
1447
+ altText
1448
+ url
1449
+ width
1450
+ height
1451
+ }
1452
+ priceRange {
1453
+ minVariantPrice {
1454
+ ...MoneyProductItem
1455
+ }
1456
+ maxVariantPrice {
1457
+ ...MoneyProductItem
1458
+ }
1459
+ }
1460
+ - variants(first: 1) {
1461
+ - nodes {
1462
+ - selectedOptions {
1463
+ - name
1464
+ - value
1465
+ - }
1466
+ - }
1467
+ - }
1468
+ }
1469
+ ` as const;
1470
+ ```
1471
+
1472
+ and remove the variant reference
1473
+
1474
+ ```diff
1475
+ function ProductItem({
1476
+ product,
1477
+ loading,
1478
+ }: {
1479
+ product: ProductItemFragment;
1480
+ loading?: 'eager' | 'lazy';
1481
+ }) {
1482
+ - const variant = product.variants.nodes[0];
1483
+ - const variantUrl = useVariantUrl(product.handle, variant.selectedOptions);
1484
+ + const variantUrl = useVariantUrl(product.handle);
1485
+ return (
1486
+ ```
1487
+
1488
+ 13. Update `routes/search.tsx`
1489
+
1490
+ Instead of using the first variant, use `selectedOrFirstAvailableVariant`
1491
+
1492
+ ```diff
1493
+ const SEARCH_PRODUCT_FRAGMENT = `#graphql
1494
+ fragment SearchProduct on Product {
1495
+ __typename
1496
+ handle
1497
+ id
1498
+ publishedAt
1499
+ title
1500
+ trackingParameters
1501
+ vendor
1502
+ - variants(first: 1) {
1503
+ - nodes {
1504
+ + selectedOrFirstAvailableVariant(
1505
+ + selectedOptions: []
1506
+ + ignoreUnknownOptions: true
1507
+ + caseInsensitiveMatch: true
1508
+ + ) {
1509
+ id
1510
+ image {
1511
+ url
1512
+ altText
1513
+ width
1514
+ height
1515
+ }
1516
+ price {
1517
+ amount
1518
+ currencyCode
1519
+ }
1520
+ compareAtPrice {
1521
+ amount
1522
+ currencyCode
1523
+ }
1524
+ selectedOptions {
1525
+ name
1526
+ value
1527
+ }
1528
+ product {
1529
+ handle
1530
+ title
1531
+ }
1532
+ }
1533
+ - }
1534
+ }
1535
+ ` as const;
1536
+ ```
1537
+
1538
+ ```diff
1539
+ const PREDICTIVE_SEARCH_PRODUCT_FRAGMENT = `#graphql
1540
+ fragment PredictiveProduct on Product {
1541
+ __typename
1542
+ id
1543
+ title
1544
+ handle
1545
+ trackingParameters
1546
+ - variants(first: 1) {
1547
+ - nodes {
1548
+ + selectedOrFirstAvailableVariant(
1549
+ + selectedOptions: []
1550
+ + ignoreUnknownOptions: true
1551
+ + caseInsensitiveMatch: true
1552
+ + ) {
1553
+ id
1554
+ image {
1555
+ url
1556
+ altText
1557
+ width
1558
+ height
1559
+ }
1560
+ price {
1561
+ amount
1562
+ currencyCode
1563
+ }
1564
+ }
1565
+ - }
1566
+ }
1567
+ ```
1568
+
1569
+ 14. Update `components/SearchResults.tsx`
1570
+
1571
+ ```diff
1572
+ function SearchResultsProducts({
1573
+ term,
1574
+ products,
1575
+ }: PartialSearchResult<'products'>) {
1576
+ if (!products?.nodes.length) {
1577
+ return null;
1578
+ }
1579
+
1580
+ return (
1581
+ <div className="search-result">
1582
+ <h2>Products</h2>
1583
+ <Pagination connection={products}>
1584
+ {({nodes, isLoading, NextLink, PreviousLink}) => {
1585
+ const ItemsMarkup = nodes.map((product) => {
1586
+ const productUrl = urlWithTrackingParams({
1587
+ baseUrl: `/products/${product.handle}`,
1588
+ trackingParams: product.trackingParameters,
1589
+ term,
1590
+ });
1591
+
1592
+ + const price = product?.selectedOrFirstAvailableVariant?.price;
1593
+ + const image = product?.selectedOrFirstAvailableVariant?.image;
1594
+
1595
+ return (
1596
+ <div className="search-results-item" key={product.id}>
1597
+ <Link prefetch="intent" to={productUrl}>
1598
+ - {product.variants.nodes[0].image && (
1599
+ + {image && (
1600
+ <Image
1601
+ - data={product.variants.nodes[0].image}
1602
+ + data={image}
1603
+ alt={product.title}
1604
+ width={50}
1605
+ />
1606
+ )}
1607
+ <div>
1608
+ <p>{product.title}</p>
1609
+ <small>
1610
+ - <Money data={product.variants.nodes[0].price} />
1611
+ + {price &&
1612
+ + <Money data={price} />
1613
+ + }
1614
+ </small>
1615
+ </div>
1616
+ </Link>
1617
+ </div>
1618
+ );
1619
+ });
1620
+ ```
1621
+
1622
+ 15. Update `components/SearchResultsPredictive.tsx`
1623
+
1624
+ ```diff
1625
+ function SearchResultsPredictiveProducts({
1626
+ term,
1627
+ products,
1628
+ closeSearch,
1629
+ }: PartialPredictiveSearchResult<'products'>) {
1630
+ if (!products.length) return null;
1631
+
1632
+ return (
1633
+ <div className="predictive-search-result" key="products">
1634
+ <h5>Products</h5>
1635
+ <ul>
1636
+ {products.map((product) => {
1637
+ const productUrl = urlWithTrackingParams({
1638
+ baseUrl: `/products/${product.handle}`,
1639
+ trackingParams: product.trackingParameters,
1640
+ term: term.current,
1641
+ });
1642
+
1643
+ + const price = product?.selectedOrFirstAvailableVariant?.price;
1644
+ - const image = product?.variants?.nodes?.[0].image;
1645
+ + const image = product?.selectedOrFirstAvailableVariant?.image;
1646
+ return (
1647
+ <li className="predictive-search-result-item" key={product.id}>
1648
+ <Link to={productUrl} onClick={closeSearch}>
1649
+ {image && (
1650
+ <Image
1651
+ alt={image.altText ?? ''}
1652
+ src={image.url}
1653
+ width={50}
1654
+ height={50}
1655
+ />
1656
+ )}
1657
+ <div>
1658
+ <p>{product.title}</p>
1659
+ <small>
1660
+ - {product?.variants?.nodes?.[0].price && (
1661
+ + {price && (
1662
+ - <Money data={product.variants.nodes[0].price} />
1663
+ + <Money data={price} />
1664
+ )}
1665
+ </small>
1666
+ </div>
1667
+ </Link>
1668
+ </li>
1669
+ );
1670
+ })}
1671
+ </ul>
1672
+ </div>
1673
+ );
1674
+ }
1675
+ ```
1676
+
1677
+ - Update `Aside` to have an accessible close button label ([#2639](https://github.com/Shopify/hydrogen/pull/2639)) by [@lb-](https://github.com/lb-)
1678
+
1679
+ - Fix cart route so that it works with no-js ([#2665](https://github.com/Shopify/hydrogen/pull/2665)) by [@wizardlyhel](https://github.com/wizardlyhel)
1680
+
1681
+ - Bump Shopify cli version ([#2667](https://github.com/Shopify/hydrogen/pull/2667)) by [@wizardlyhel](https://github.com/wizardlyhel)
1682
+
1683
+ - Updated dependencies [[`8f64915e`](https://github.com/Shopify/hydrogen/commit/8f64915e934130299307417627a12caf756cd8da), [`a57d5267`](https://github.com/Shopify/hydrogen/commit/a57d5267daa2f22fe1a426fb9f62c242957f95b6), [`91d60fd2`](https://github.com/Shopify/hydrogen/commit/91d60fd2174b7c34f9f6b781cd5f0a70371fd899), [`23a80f3e`](https://github.com/Shopify/hydrogen/commit/23a80f3e7bf9f9908130fc9345397fc694420364)]:
1684
+ - @shopify/hydrogen@2024.10.1
1685
+
1686
+ ## 2024.10.1
1687
+
1688
+ ### Patch Changes
1689
+
1690
+ - Bump to get new cli package version by [@wizardlyhel](https://github.com/wizardlyhel)
1691
+
1692
+ ## 2024.10.0
1693
+
1694
+ ### Patch Changes
1695
+
1696
+ - Stabilize `getSitemap`, `getSitemapIndex` and implement on skeleton ([#2589](https://github.com/Shopify/hydrogen/pull/2589)) by [@juanpprieto](https://github.com/juanpprieto)
1697
+ 1. Update the `getSitemapIndex` at `/app/routes/[sitemap.xml].tsx`
1698
+
1699
+ ```diff
1700
+ - import {unstable__getSitemapIndex as getSitemapIndex} from '@shopify/hydrogen';
1701
+ + import {getSitemapIndex} from '@shopify/hydrogen';
1702
+ ```
1703
+
1704
+ 2. Update the `getSitemap` at `/app/routes/sitemap.$type.$page[.xml].tsx`
1705
+
1706
+ ```diff
1707
+ - import {unstable__getSitemap as getSitemap} from '@shopify/hydrogen';
1708
+ + import {getSitemap} from '@shopify/hydrogen';
1709
+ ```
1710
+
1711
+ For a reference implementation please see the skeleton template sitemap routes
1712
+
1713
+ - [**Breaking change**] ([#2588](https://github.com/Shopify/hydrogen/pull/2588)) by [@wizardlyhel](https://github.com/wizardlyhel)
1714
+
1715
+ Set up Customer Privacy without the Shopify's cookie banner by default.
1716
+
1717
+ If you are using Shopify's cookie banner to handle user consent in your app, you need to set `withPrivacyBanner: true` to the consent config. Without this update, the Shopify cookie banner will not appear.
1718
+
1719
+ ```diff
1720
+ return defer({
1721
+ ...
1722
+ consent: {
1723
+ checkoutDomain: env.PUBLIC_CHECKOUT_DOMAIN,
1724
+ storefrontAccessToken: env.PUBLIC_STOREFRONT_API_TOKEN,
1725
+ + withPrivacyBanner: true,
1726
+ // localize the privacy banner
1727
+ country: args.context.storefront.i18n.country,
1728
+ language: args.context.storefront.i18n.language,
1729
+ },
1730
+ });
1731
+ ```
1732
+
1733
+ - Update to 2024-10 SFAPI ([#2570](https://github.com/Shopify/hydrogen/pull/2570)) by [@wizardlyhel](https://github.com/wizardlyhel)
1734
+
1735
+ - [**Breaking change**] ([#2546](https://github.com/Shopify/hydrogen/pull/2546)) by [@frandiox](https://github.com/frandiox)
1736
+
1737
+ Update `createWithCache` to make it harder to accidentally cache undesired results. `request` is now mandatory prop when initializing `createWithCache`.
1738
+
1739
+ ```diff
1740
+ // server.ts
1741
+ export default {
1742
+ async fetch(
1743
+ request: Request,
1744
+ env: Env,
1745
+ executionContext: ExecutionContext,
1746
+ ): Promise<Response> {
1747
+ try {
1748
+ // ...
1749
+ - const withCache = createWithCache({cache, waitUntil});
1750
+ + const withCache = createWithCache({cache, waitUntil, request});
1751
+ ```
1752
+
1753
+ `createWithCache` now returns an object with two utility functions: `withCache.run` and `withCache.fetch`. Both have a new prop `shouldCacheResult` that must be defined.
1754
+
1755
+ The original `withCache` callback function is now `withCache.run`. This is useful to run _multiple_ fetch calls and merge their responses, or run any arbitrary code. It caches anything you return, but you can throw if you don't want to cache anything.
1756
+
1757
+ ```diff
1758
+ const withCache = createWithCache({cache, waitUntil, request});
1759
+
1760
+ const fetchMyCMS = (query) => {
1761
+ - return withCache(['my-cms', query], CacheLong(), async (params) => {
1762
+ + return withCache.run({
1763
+ + cacheKey: ['my-cms', query],
1764
+ + cacheStrategy: CacheLong(),
1765
+ + // Cache if there are no data errors or a specific data that make this result not suited for caching
1766
+ + shouldCacheResult: (result) => !result?.errors,
1767
+ + }, async(params) => {
1768
+ const response = await fetch('my-cms.com/api', {
1769
+ method: 'POST',
1770
+ body: query,
1771
+ });
1772
+ if (!response.ok) throw new Error(response.statusText);
1773
+ const {data, error} = await response.json();
1774
+ if (error || !data) throw new Error(error ?? 'Missing data');
1775
+ params.addDebugData({displayName: 'My CMS query', response});
1776
+ return data;
1777
+ });
1778
+ };
1779
+ ```
1780
+
1781
+ New `withCache.fetch` is for caching simple fetch requests. This method caches the responses if they are OK responses, and you can pass `shouldCacheResponse`, `cacheKey`, etc. to modify behavior. `data` is the consumed body of the response (we need to consume to cache it).
1782
+
1783
+ ```ts
1784
+ const withCache = createWithCache({cache, waitUntil, request});
1785
+
1786
+ const {data, response} = await withCache.fetch<{data: T; error: string}>(
1787
+ 'my-cms.com/api',
1788
+ {
1789
+ method: 'POST',
1790
+ headers: {'Content-type': 'application/json'},
1791
+ body,
1792
+ },
1793
+ {
1794
+ cacheStrategy: CacheLong(),
1795
+ // Cache if there are no data errors or a specific data that make this result not suited for caching
1796
+ shouldCacheResponse: (result) => !result?.error,
1797
+ cacheKey: ['my-cms', body],
1798
+ displayName: 'My CMS query',
1799
+ },
1800
+ );
1801
+ ```
1802
+
1803
+ - [**Breaking change**] ([#2585](https://github.com/Shopify/hydrogen/pull/2585)) by [@wizardlyhel](https://github.com/wizardlyhel)
1804
+
1805
+ Deprecate usages of `product.options.values` and use `product.options.optionValues` instead.
1806
+ 1. Update your product graphql query to use the new `optionValues` field.
1807
+
1808
+ ```diff
1809
+ const PRODUCT_FRAGMENT = `#graphql
1810
+ fragment Product on Product {
1811
+ id
1812
+ title
1813
+ options {
1814
+ name
1815
+ - values
1816
+ + optionValues {
1817
+ + name
1818
+ + }
1819
+ }
1820
+ ```
1821
+
1822
+ 2. Update your `<VariantSelector>` to use the new `optionValues` field.
1823
+
1824
+ ```diff
1825
+ <VariantSelector
1826
+ handle={product.handle}
1827
+ - options={product.options.filter((option) => option.values.length > 1)}
1828
+ + options={product.options.filter((option) => option.optionValues.length > 1)}
1829
+ variants={variants}
1830
+ >
1831
+ ```
1832
+
1833
+ - Updated dependencies [[`d97cd56e`](https://github.com/Shopify/hydrogen/commit/d97cd56e859abf8dd005fef2589d99e07fa87b6e), [`809c9f3d`](https://github.com/Shopify/hydrogen/commit/809c9f3d342b56dd3c0d340cb733e6f00053b71d), [`8c89f298`](https://github.com/Shopify/hydrogen/commit/8c89f298a8d9084ee510fb4d0d17766ec43c249c), [`a253ef97`](https://github.com/Shopify/hydrogen/commit/a253ef971acb08f2ee3a2743ca5c901c2922acc0), [`84a66b1e`](https://github.com/Shopify/hydrogen/commit/84a66b1e9d07bd6d6a10e5379ad3350b6bbecde9), [`227035e7`](https://github.com/Shopify/hydrogen/commit/227035e7e11df5fec5ac475b98fa6a318bdbe366), [`ac12293c`](https://github.com/Shopify/hydrogen/commit/ac12293c7b36e1b278bc929c682c65779c300cc7), [`c7c9f2eb`](https://github.com/Shopify/hydrogen/commit/c7c9f2ebd869a9d361504a10566c268e88b6096a), [`76cd4f9b`](https://github.com/Shopify/hydrogen/commit/76cd4f9ba3dd8eff4433d72f4422c06a7d567537), [`8337e534`](https://github.com/Shopify/hydrogen/commit/8337e5342ecca563fab557c3e833485466456cd5)]:
1834
+ - @shopify/hydrogen@2024.10.0
1835
+ - @shopify/remix-oxygen@2.0.9
1836
+
1837
+ ## 2024.7.10
1838
+
1839
+ ### Patch Changes
1840
+
1841
+ - Use HTML datalist element for query suggestions for autocomplete experience ([#2506](https://github.com/Shopify/hydrogen/pull/2506)) by [@frontsideair](https://github.com/frontsideair)
1842
+
1843
+ - Bump cli packages version ([#2592](https://github.com/Shopify/hydrogen/pull/2592)) by [@wizardlyhel](https://github.com/wizardlyhel)
1844
+
1845
+ - Updated dependencies [[`e963389d`](https://github.com/Shopify/hydrogen/commit/e963389d011b1cb44e2874fa332dc355c0d38eb9), [`d08d8c37`](https://github.com/Shopify/hydrogen/commit/d08d8c3779564cc55749f24bed1f6a2958a0a865)]:
1846
+ - @shopify/hydrogen@2024.7.9
1847
+
1848
+ ## 2024.7.9
1849
+
1850
+ ### Patch Changes
1851
+
1852
+ - Updated dependencies [[`f3363030`](https://github.com/Shopify/hydrogen/commit/f3363030a50bd24d946427e01b88ba77253a6cc9), [`bb5b0979`](https://github.com/Shopify/hydrogen/commit/bb5b0979ddffb007111885b3a9b7aa490a3c6882)]:
1853
+ - @shopify/hydrogen@2024.7.8
1854
+ - @shopify/remix-oxygen@2.0.8
1855
+
1856
+ ## 2024.7.8
1857
+
1858
+ ### Patch Changes
1859
+
1860
+ - Updated dependencies [[`39f8f8fd`](https://github.com/Shopify/hydrogen/commit/39f8f8fd42766d02c6e98f8090608e641db9f002)]:
1861
+ - @shopify/hydrogen@2024.7.7
1862
+
1863
+ ## 2024.7.7
1864
+
1865
+ ### Patch Changes
1866
+
1867
+ - Updated dependencies [[`d0ff37a9`](https://github.com/Shopify/hydrogen/commit/d0ff37a995bb64598930f8aa53f2612f3b1ea476)]:
1868
+ - @shopify/hydrogen@2024.7.6
1869
+
1870
+ ## 2024.7.6
1871
+
1872
+ ### Patch Changes
1873
+
1874
+ - Update Shopify CLI and cli-kit dependencies to 3.66.1 ([#2512](https://github.com/Shopify/hydrogen/pull/2512)) by [@frandiox](https://github.com/frandiox)
1875
+
1876
+ - createCartHandler supplies updateGiftCardCodes method ([#2298](https://github.com/Shopify/hydrogen/pull/2298)) by [@wizardlyhel](https://github.com/wizardlyhel)
1877
+
1878
+ - Fix menu links in side panel not working on mobile devices ([#2450](https://github.com/Shopify/hydrogen/pull/2450)) by [@wizardlyhel](https://github.com/wizardlyhel)
1879
+
1880
+ ```diff
1881
+ // /app/components/Header.tsx
1882
+
1883
+ export function HeaderMenu({
1884
+ menu,
1885
+ primaryDomainUrl,
1886
+ viewport,
1887
+ publicStoreDomain,
1888
+ }: {
1889
+ menu: HeaderProps['header']['menu'];
1890
+ primaryDomainUrl: HeaderProps['header']['shop']['primaryDomain']['url'];
1891
+ viewport: Viewport;
1892
+ publicStoreDomain: HeaderProps['publicStoreDomain'];
1893
+ }) {
1894
+ const className = `header-menu-${viewport}`;
1895
+ + const {close} = useAside();
1896
+
1897
+ - function closeAside(event: React.MouseEvent<HTMLAnchorElement>) {
1898
+ - if (viewport === 'mobile') {
1899
+ - event.preventDefault();
1900
+ - window.location.href = event.currentTarget.href;
1901
+ - }
1902
+ - }
1903
+
1904
+ return (
1905
+ <nav className={className} role="navigation">
1906
+ {viewport === 'mobile' && (
1907
+ <NavLink
1908
+ end
1909
+ - onClick={closeAside}
1910
+ + onClick={close}
1911
+ prefetch="intent"
1912
+ style={activeLinkStyle}
1913
+ to="/"
1914
+ >
1915
+ Home
1916
+ </NavLink>
1917
+ )}
1918
+ {(menu || FALLBACK_HEADER_MENU).items.map((item) => {
1919
+ if (!item.url) return null;
1920
+
1921
+ // if the url is internal, we strip the domain
1922
+ const url =
1923
+ item.url.includes('myshopify.com') ||
1924
+ item.url.includes(publicStoreDomain) ||
1925
+ item.url.includes(primaryDomainUrl)
1926
+ ? new URL(item.url).pathname
1927
+ : item.url;
1928
+ return (
1929
+ <NavLink
1930
+ className="header-menu-item"
1931
+ end
1932
+ key={item.id}
1933
+ - onClick={closeAside}
1934
+ + onClick={close}
1935
+ prefetch="intent"
1936
+ style={activeLinkStyle}
1937
+ to={url}
1938
+ >
1939
+ {item.title}
1940
+ </NavLink>
1941
+ );
1942
+ })}
1943
+ </nav>
1944
+ );
1945
+ }
1946
+ ```
1947
+
1948
+ - Add localization support to consent privacy banner ([#2457](https://github.com/Shopify/hydrogen/pull/2457)) by [@juanpprieto](https://github.com/juanpprieto)
1949
+
1950
+ - Updated dependencies [[`d633e49a`](https://github.com/Shopify/hydrogen/commit/d633e49aff244a985c58ec77fc2796c9c1cd5df4), [`1b217cd6`](https://github.com/Shopify/hydrogen/commit/1b217cd68ffd5362d201d4bd225ec72e99713461), [`d929b561`](https://github.com/Shopify/hydrogen/commit/d929b5612ec28e53ec216844add33682f131aba7), [`664a09d5`](https://github.com/Shopify/hydrogen/commit/664a09d57ef5d3c67da947a4e8546527c01e37c4), [`0c1e511d`](https://github.com/Shopify/hydrogen/commit/0c1e511df72e9605534bb9c960e86d5c9a4bf2ea), [`eefa8203`](https://github.com/Shopify/hydrogen/commit/eefa820383fa93657ca214991f6099ce9268a4ee)]:
1951
+ - @shopify/hydrogen@2024.7.5
1952
+ - @shopify/remix-oxygen@2.0.7
1953
+
1954
+ ## 2024.7.5
1955
+
1956
+ ### Patch Changes
1957
+
1958
+ - Updated dependencies [[`b0d3bc06`](https://github.com/Shopify/hydrogen/commit/b0d3bc0696d266fcfc4eb93d0a4adb9ccb56ade6)]:
1959
+ - @shopify/hydrogen@2024.7.4
1960
+
1961
+ ## 2024.7.4
1962
+
1963
+ ### Patch Changes
1964
+
1965
+ - Search & Predictive Search improvements ([#2363](https://github.com/Shopify/hydrogen/pull/2363)) by [@juanpprieto](https://github.com/juanpprieto)
1966
+
1967
+ - 1. Create a app/lib/context file and use `createHydrogenContext` in it. ([#2333](https://github.com/Shopify/hydrogen/pull/2333)) by [@michenly](https://github.com/michenly)
1968
+
1969
+ ```.ts
1970
+ // in app/lib/context
1971
+
1972
+ import {createHydrogenContext} from '@shopify/hydrogen';
1973
+
1974
+ export async function createAppLoadContext(
1975
+ request: Request,
1976
+ env: Env,
1977
+ executionContext: ExecutionContext,
1978
+ ) {
1979
+ const hydrogenContext = createHydrogenContext({
1980
+ env,
1981
+ request,
1982
+ cache,
1983
+ waitUntil,
1984
+ session,
1985
+ i18n: {language: 'EN', country: 'US'},
1986
+ cart: {
1987
+ queryFragment: CART_QUERY_FRAGMENT,
1988
+ },
1989
+ // ensure to overwrite any options that is not using the default values from your server.ts
1990
+ });
1991
+
1992
+ return {
1993
+ ...hydrogenContext,
1994
+ // declare additional Remix loader context
1995
+ };
1996
+ }
1997
+
1998
+ ```
1999
+
2000
+ 2. Use `createAppLoadContext` method in server.ts Ensure to overwrite any options that is not using the default values in `createHydrogenContext`.
2001
+
2002
+ ```diff
2003
+ // in server.ts
2004
+
2005
+ - import {
2006
+ - createCartHandler,
2007
+ - createStorefrontClient,
2008
+ - createCustomerAccountClient,
2009
+ - } from '@shopify/hydrogen';
2010
+ + import {createAppLoadContext} from '~/lib/context';
2011
+
2012
+ export default {
2013
+ async fetch(
2014
+ request: Request,
2015
+ env: Env,
2016
+ executionContext: ExecutionContext,
2017
+ ): Promise<Response> {
2018
+
2019
+ - const {storefront} = createStorefrontClient(
2020
+ - ...
2021
+ - );
2022
+
2023
+ - const customerAccount = createCustomerAccountClient(
2024
+ - ...
2025
+ - );
2026
+
2027
+ - const cart = createCartHandler(
2028
+ - ...
2029
+ - );
2030
+
2031
+ + const appLoadContext = await createAppLoadContext(
2032
+ + request,
2033
+ + env,
2034
+ + executionContext,
2035
+ + );
2036
+
2037
+ /**
2038
+ * Create a Remix request handler and pass
2039
+ * Hydrogen's Storefront client to the loader context.
2040
+ */
2041
+ const handleRequest = createRequestHandler({
2042
+ build: remixBuild,
2043
+ mode: process.env.NODE_ENV,
2044
+ - getLoadContext: (): AppLoadContext => ({
2045
+ - session,
2046
+ - storefront,
2047
+ - customerAccount,
2048
+ - cart,
2049
+ - env,
2050
+ - waitUntil,
2051
+ - }),
2052
+ + getLoadContext: () => appLoadContext,
2053
+ });
2054
+ }
2055
+ ```
2056
+
2057
+ 3. Use infer type for AppLoadContext in env.d.ts
2058
+
2059
+ ```diff
2060
+ // in env.d.ts
2061
+
2062
+ + import type {createAppLoadContext} from '~/lib/context';
2063
+
2064
+ + interface AppLoadContext extends Awaited<ReturnType<typeof createAppLoadContext>> {
2065
+ - interface AppLoadContext {
2066
+ - env: Env;
2067
+ - cart: HydrogenCart;
2068
+ - storefront: Storefront;
2069
+ - customerAccount: CustomerAccount;
2070
+ - session: AppSession;
2071
+ - waitUntil: ExecutionContext['waitUntil'];
2072
+ }
2073
+
2074
+ ```
2075
+
2076
+ - Use type `HydrogenEnv` for all the env.d.ts ([#2333](https://github.com/Shopify/hydrogen/pull/2333)) by [@michenly](https://github.com/michenly)
2077
+
2078
+ ```diff
2079
+ // in env.d.ts
2080
+
2081
+ + import type {HydrogenEnv} from '@shopify/hydrogen';
2082
+
2083
+ + interface Env extends HydrogenEnv {}
2084
+ - interface Env {
2085
+ - SESSION_SECRET: string;
2086
+ - PUBLIC_STOREFRONT_API_TOKEN: string;
2087
+ - PRIVATE_STOREFRONT_API_TOKEN: string;
2088
+ - PUBLIC_STORE_DOMAIN: string;
2089
+ - PUBLIC_STOREFRONT_ID: string;
2090
+ - PUBLIC_CUSTOMER_ACCOUNT_API_CLIENT_ID: string;
2091
+ - PUBLIC_CUSTOMER_ACCOUNT_API_URL: string;
2092
+ - PUBLIC_CHECKOUT_DOMAIN: string;
2093
+ - }
2094
+
2095
+ ```
2096
+
2097
+ - Add a hydration check for google web cache. This prevents an infinite redirect when viewing the cached version of a hydrogen site on Google. ([#2334](https://github.com/Shopify/hydrogen/pull/2334)) by [@blittle](https://github.com/blittle)
2098
+
2099
+ Update your entry.server.jsx file to include this check:
2100
+
2101
+ ```diff
2102
+ + if (!window.location.origin.includes("webcache.googleusercontent.com")) {
2103
+ startTransition(() => {
2104
+ hydrateRoot(
2105
+ document,
2106
+ <StrictMode>
2107
+ <RemixBrowser />
2108
+ </StrictMode>
2109
+ );
2110
+ });
2111
+ + }
2112
+ ```
2113
+
2114
+ - Updated dependencies [[`a2d9acf9`](https://github.com/Shopify/hydrogen/commit/a2d9acf95e019c39df0b10f4841a1d809b810c80), [`c0d7d917`](https://github.com/Shopify/hydrogen/commit/c0d7d9176c80b996064d8e897876f954807c7640), [`b09e9a4c`](https://github.com/Shopify/hydrogen/commit/b09e9a4ca7b931e48462c2d174ca9f67c37f1da2), [`c204eacf`](https://github.com/Shopify/hydrogen/commit/c204eacf0273f625109523ee81053cdc0c4de7e1), [`bf4e3d3c`](https://github.com/Shopify/hydrogen/commit/bf4e3d3c00744a066b50250a12e4f3c675691811), [`20a8e63b`](https://github.com/Shopify/hydrogen/commit/20a8e63b5fd1c8acadda7612c5d4cc411e0c5932), [`6e5d8ea7`](https://github.com/Shopify/hydrogen/commit/6e5d8ea71a2639925d5817b662af26a6b2ba3c6d), [`7c4f67a6`](https://github.com/Shopify/hydrogen/commit/7c4f67a684ad31edea10d1407d00201bbaaa9822), [`dfb9be77`](https://github.com/Shopify/hydrogen/commit/dfb9be7721c7d10cf4354fda60db4e666625518e), [`31ea19e8`](https://github.com/Shopify/hydrogen/commit/31ea19e8957dbc4487314b014a14920444d37f78)]:
2115
+ - @shopify/cli-hydrogen@8.4.0
2116
+ - @shopify/hydrogen@2024.7.3
2117
+ - @shopify/remix-oxygen@2.0.6
2118
+
2119
+ ## 2024.7.3
2120
+
2121
+ ### Patch Changes
2122
+
2123
+ - Updated dependencies [[`150854ed`](https://github.com/Shopify/hydrogen/commit/150854ed1352245eef180cc6b2bceb41dd8cc898)]:
2124
+ - @shopify/hydrogen@2024.7.2
2125
+
2126
+ ## 2024.7.2
2127
+
2128
+ ### Patch Changes
2129
+
2130
+ - Changed the GraphQL config file format to be TS/JS instead of YAML. ([#2311](https://github.com/Shopify/hydrogen/pull/2311)) by [@frandiox](https://github.com/frandiox)
2131
+
2132
+ - Updated dependencies [[`18ea233c`](https://github.com/Shopify/hydrogen/commit/18ea233cd327bf3001ec9b107ad66b05c9c78584), [`8b2322d7`](https://github.com/Shopify/hydrogen/commit/8b2322d783078298cd5d20ec5f3b1faf99b7895b)]:
2133
+ - @shopify/cli-hydrogen@8.3.0
2134
+
2135
+ ## 2024.7.1
2136
+
2137
+ ### Patch Changes
2138
+
2139
+ - Update `@shopify/oxygen-workers-types` to fix issues on Windows. ([#2252](https://github.com/Shopify/hydrogen/pull/2252)) by [@michenly](https://github.com/michenly)
2140
+
2141
+ - [**Breaking change**] ([#2113](https://github.com/Shopify/hydrogen/pull/2113)) by [@blittle](https://github.com/blittle)
2142
+
2143
+ Previously the `VariantSelector` component would filter out options that only had one value. This is undesireable for some apps. We've removed that filter, if you'd like to retain the existing functionality, simply filter the options prop before it is passed to the `VariantSelector` component:
2144
+
2145
+ ```diff
2146
+ <VariantSelector
2147
+ handle={product.handle}
2148
+ + options={product.options.filter((option) => option.values.length > 1)}
2149
+ - options={product.options}
2150
+ variants={variants}>
2151
+ </VariantSelector>
2152
+ ```
2153
+
2154
+ Fixes [#1198](https://github.com/Shopify/hydrogen/discussions/1198)
2155
+
2156
+ - Update remix to v2.10.1 ([#2290](https://github.com/Shopify/hydrogen/pull/2290)) by [@michenly](https://github.com/michenly)
2157
+
2158
+ - Update root to use [Remix's Layout Export pattern](https://remix.run/docs/en/main/file-conventions/root#layout-export) and eliminate the use of `useLoaderData` in root. ([#2292](https://github.com/Shopify/hydrogen/pull/2292)) by [@michenly](https://github.com/michenly)
2159
+
2160
+ The diff below showcase how you can make this refactor in existing application.
2161
+
2162
+ ```diff
2163
+ import {
2164
+ Outlet,
2165
+ - useLoaderData,
2166
+ + useRouteLoaderData,
2167
+ } from '@remix-run/react';
2168
+ -import {Layout} from '~/components/Layout';
2169
+ +import {PageLayout} from '~/components/PageLayout';
2170
+
2171
+ -export default function App() {
2172
+ +export function Layout({children}: {children?: React.ReactNode}) {
2173
+ const nonce = useNonce();
2174
+ - const data = useLoaderData<typeof loader>();
2175
+ + const data = useRouteLoaderData<typeof loader>('root');
2176
+
2177
+ return (
2178
+ <html>
2179
+ ...
2180
+ <body>
2181
+ - <Layout {...data}>
2182
+ - <Outlet />
2183
+ - </Layout>
2184
+ + {data? (
2185
+ + <PageLayout {...data}>{children}</PageLayout>
2186
+ + ) : (
2187
+ + children
2188
+ + )}
2189
+ </body>
2190
+ </html>
2191
+ );
2192
+ }
2193
+
2194
+ +export default function App() {
2195
+ + return <Outlet />;
2196
+ +}
2197
+
2198
+ export function ErrorBoundary() {
2199
+ - const rootData = useLoaderData<typeof loader>();
2200
+
2201
+ return (
2202
+ - <html>
2203
+ - ...
2204
+ - <body>
2205
+ - <Layout {...rootData}>
2206
+ - <div className="route-error">
2207
+ - <h1>Error</h1>
2208
+ - ...
2209
+ - </div>
2210
+ - </Layout>
2211
+ - </body>
2212
+ - </html>
2213
+ + <div className="route-error">
2214
+ + <h1>Error</h1>
2215
+ + ...
2216
+ + </div>
2217
+ );
2218
+ }
2219
+
2220
+ ```
2221
+
2222
+ - Refactor the cart and product form components ([#2132](https://github.com/Shopify/hydrogen/pull/2132)) by [@blittle](https://github.com/blittle)
2223
+
2224
+ - Remove manual setting of session in headers and recommend setting it in server after response is created. ([#2137](https://github.com/Shopify/hydrogen/pull/2137)) by [@michenly](https://github.com/michenly)
2225
+
2226
+ Step 1: Add `isPending` implementation in session
2227
+
2228
+ ```diff
2229
+ // in app/lib/session.ts
2230
+ export class AppSession implements HydrogenSession {
2231
+ + public isPending = false;
2232
+
2233
+ get unset() {
2234
+ + this.isPending = true;
2235
+ return this.#session.unset;
2236
+ }
2237
+
2238
+ get set() {
2239
+ + this.isPending = true;
2240
+ return this.#session.set;
2241
+ }
2242
+
2243
+ commit() {
2244
+ + this.isPending = false;
2245
+ return this.#sessionStorage.commitSession(this.#session);
2246
+ }
2247
+ }
2248
+ ```
2249
+
2250
+ Step 2: update response header if `session.isPending` is true
2251
+
2252
+ ```diff
2253
+ // in server.ts
2254
+ export default {
2255
+ async fetch(request: Request): Promise<Response> {
2256
+ try {
2257
+ const response = await handleRequest(request);
2258
+
2259
+ + if (session.isPending) {
2260
+ + response.headers.set('Set-Cookie', await session.commit());
2261
+ + }
2262
+
2263
+ return response;
2264
+ } catch (error) {
2265
+ ...
2266
+ }
2267
+ },
2268
+ };
2269
+ ```
2270
+
2271
+ Step 3: remove setting cookie with session.commit() in routes
2272
+
2273
+ ```diff
2274
+ // in route files
2275
+ export async function loader({context}: LoaderFunctionArgs) {
2276
+ return json({},
2277
+ - {
2278
+ - headers: {
2279
+ - 'Set-Cookie': await context.session.commit(),
2280
+ - },
2281
+ },
2282
+ );
2283
+ }
2284
+ ```
2285
+
2286
+ - Moved `@shopify/cli` from `dependencies` to `devDependencies`. ([#2312](https://github.com/Shopify/hydrogen/pull/2312)) by [@frandiox](https://github.com/frandiox)
2287
+
2288
+ - The `@shopify/cli` package now bundles the `@shopify/cli-hydrogen` plugin. Therefore, you can now remove the latter from your local dependencies: ([#2306](https://github.com/Shopify/hydrogen/pull/2306)) by [@frandiox](https://github.com/frandiox)
2289
+
2290
+ ```diff
2291
+ "@shopify/cli": "3.64.0",
2292
+ - "@shopify/cli-hydrogen": "^8.1.1",
2293
+ "@shopify/hydrogen": "2024.7.0",
2294
+ ```
2295
+
2296
+ - Updated dependencies [[`a0e84d76`](https://github.com/Shopify/hydrogen/commit/a0e84d76b67d4c57c4defee06185949c41782eab), [`426bb390`](https://github.com/Shopify/hydrogen/commit/426bb390b25f51e57499ff6673aef70ded935e87), [`4337200c`](https://github.com/Shopify/hydrogen/commit/4337200c7908d56c039171c283a4d92c31a8b7b6), [`710625c7`](https://github.com/Shopify/hydrogen/commit/710625c740a6656488d4b419e2d2451bef9d076f), [`8b9c726d`](https://github.com/Shopify/hydrogen/commit/8b9c726d34f3482b5b5a0da4c7c0c2f20e2c9caa), [`10a419bf`](https://github.com/Shopify/hydrogen/commit/10a419bf1db79cdfd8c41c0223ce695959f60da9), [`6a6278bb`](https://github.com/Shopify/hydrogen/commit/6a6278bb9187b3b5a98cd98ec9dd278882d03c0d), [`66236ca6`](https://github.com/Shopify/hydrogen/commit/66236ca65ddefac99eaa553c7877c85863d84cc2), [`dcbd0bbf`](https://github.com/Shopify/hydrogen/commit/dcbd0bbf4073a3e35e96f3cce257f7b19b2b2aea), [`a5e03e2a`](https://github.com/Shopify/hydrogen/commit/a5e03e2a1e99fcd83ee5a2be7bf6f5f6b47984b3), [`c2690653`](https://github.com/Shopify/hydrogen/commit/c2690653b6b24f7318e9088551a37195255a2247), [`54c2f7ad`](https://github.com/Shopify/hydrogen/commit/54c2f7ad3d0d52e6be10b2a54a1a4fd0cc107a35), [`4337200c`](https://github.com/Shopify/hydrogen/commit/4337200c7908d56c039171c283a4d92c31a8b7b6), [`e96b332b`](https://github.com/Shopify/hydrogen/commit/e96b332ba1aba79aa3d5c2ce18001292070faf49), [`f3065371`](https://github.com/Shopify/hydrogen/commit/f3065371c1dda222c6e40bd8c20528dc9fdea9a5), [`6cd5554b`](https://github.com/Shopify/hydrogen/commit/6cd5554b160d314d35964a5ee8976ed60972bf17), [`9eb60d73`](https://github.com/Shopify/hydrogen/commit/9eb60d73e552c3d22b9325ecbcd5878810893ad3), [`e432533e`](https://github.com/Shopify/hydrogen/commit/e432533e7391ec3fe16a4a24f2b3363206842580), [`de3f70be`](https://github.com/Shopify/hydrogen/commit/de3f70be1a838eda746903cbb38cc25cf0e09fa3), [`83cb96f4`](https://github.com/Shopify/hydrogen/commit/83cb96f42078bf79b20a153d8a8461f75d573ab1)]:
2297
+ - @shopify/remix-oxygen@2.0.5
2298
+ - @shopify/cli-hydrogen@8.2.0
2299
+ - @shopify/hydrogen@2024.7.1
2300
+
2301
+ ## 2024.4.5
2302
+
2303
+ ### Patch Changes
2304
+
2305
+ - Update remix to v2.9.2 ([#2135](https://github.com/Shopify/hydrogen/pull/2135)) by [@michenly](https://github.com/michenly)
2306
+
2307
+ - `<Analytics>` and `useAnalytics` are now stable. ([#2141](https://github.com/Shopify/hydrogen/pull/2141)) by [@wizardlyhel](https://github.com/wizardlyhel)
2308
+
2309
+ - Update the skeleton template to use React state in the aside dialogs ([#2088](https://github.com/Shopify/hydrogen/pull/2088)) by [@blittle](https://github.com/blittle)
2310
+
2311
+ - Updated dependencies [[`fe82119f`](https://github.com/Shopify/hydrogen/commit/fe82119f5e75df5a0f727bab6a2186e679abc73d), [`32d4c33e`](https://github.com/Shopify/hydrogen/commit/32d4c33e4421a9c56f62a8c392f5417edddd0402), [`8eea75ec`](https://github.com/Shopify/hydrogen/commit/8eea75ec5ead4de98d7d1b2baedce8511029bcae), [`27e51abf`](https://github.com/Shopify/hydrogen/commit/27e51abfc1f5444afa952c503886bfa12fc55c7e), [`f29c9085`](https://github.com/Shopify/hydrogen/commit/f29c9085eb1adbde9e01226484eba8a85b5074ed), [`7b838beb`](https://github.com/Shopify/hydrogen/commit/7b838beb7c43380ffc9c32c2bb9f34291912fa42), [`d702aec2`](https://github.com/Shopify/hydrogen/commit/d702aec2214646a78cdafc2c25d510489db73f6d), [`ca4cf045`](https://github.com/Shopify/hydrogen/commit/ca4cf045f7fb72ad98b62af7bd172ff8cf553de2), [`5a554b2e`](https://github.com/Shopify/hydrogen/commit/5a554b2e9d91894c2db8032f0c29666dce1ea3f2), [`27e51abf`](https://github.com/Shopify/hydrogen/commit/27e51abfc1f5444afa952c503886bfa12fc55c7e), [`5d6465b3`](https://github.com/Shopify/hydrogen/commit/5d6465b32d90052e5580fcb81d98427bcb8ad528), [`608389d6`](https://github.com/Shopify/hydrogen/commit/608389d6d69c6a9801935d528507c165d1dd4ccf), [`9dfd1cfe`](https://github.com/Shopify/hydrogen/commit/9dfd1cfeb3e96c6d3426427a4b5d97ef475dab6d), [`7def3e9f`](https://github.com/Shopify/hydrogen/commit/7def3e9fa6e28f4fde7af43e2f346aa32267c38e), [`65239c76`](https://github.com/Shopify/hydrogen/commit/65239c76ca1d0b294b59b1ad53624485859c4da5), [`ca7f2888`](https://github.com/Shopify/hydrogen/commit/ca7f28887367a4882e57a67c4e248b0f0bba1c9b)]:
2312
+ - @shopify/hydrogen@2024.4.3
2313
+ - @shopify/cli-hydrogen@8.1.0
2314
+
2315
+ ## 2024.4.4
2316
+
2317
+ ### Patch Changes
2318
+
2319
+ - Add JSdoc to `getSelectedProductOptions` utility and cleanup the skeleton implementation ([#2089](https://github.com/Shopify/hydrogen/pull/2089)) by [@juanpprieto](https://github.com/juanpprieto)
2320
+
2321
+ - Updated dependencies [[`286589ee`](https://github.com/Shopify/hydrogen/commit/286589ee281c161ad323e3d45a8b9b859aa5b11f), [`6f5061d9`](https://github.com/Shopify/hydrogen/commit/6f5061d9432f749fde7902548894e98c0d3f899c), [`ae262b61`](https://github.com/Shopify/hydrogen/commit/ae262b616127a7173d23a1a38a6e658af3105ce8), [`2c11ca3b`](https://github.com/Shopify/hydrogen/commit/2c11ca3b7a00ccca2b621dbc29abd319f9598cc8), [`b70f9c2c`](https://github.com/Shopify/hydrogen/commit/b70f9c2c3db8e863c65509097454b9ad7c81cd52), [`17528db1`](https://github.com/Shopify/hydrogen/commit/17528db1eb3d1baa001bafe0684b4bce28d2e271), [`58ea9bb0`](https://github.com/Shopify/hydrogen/commit/58ea9bb0f0eee83ff89e34e2f1f6ac3c4999e213)]:
2322
+ - @shopify/cli-hydrogen@8.0.4
2323
+ - @shopify/hydrogen@2024.4.2
2324
+
2325
+ ## 1.0.10
2326
+
2327
+ ### Patch Changes
2328
+
2329
+ - Update `@shopify/cli` dependency to avoid React version mismatches in your project: ([#2059](https://github.com/Shopify/hydrogen/pull/2059)) by [@frandiox](https://github.com/frandiox)
2330
+
2331
+ ```diff
2332
+ "dependencies": {
2333
+ ...
2334
+ - "@shopify/cli": "3.58.0",
2335
+ + "@shopify/cli": "3.59.2",
2336
+ ...
2337
+ }
2338
+ ```
2339
+
2340
+ - Updated dependencies [[`d2bc720b`](https://github.com/Shopify/hydrogen/commit/d2bc720bb5f7cfb5f42617f98ad2dfcd29891f4b)]:
2341
+ - @shopify/cli-hydrogen@8.0.3
2342
+
2343
+ ## 1.0.9
2344
+
2345
+ ### Patch Changes
2346
+
2347
+ - Pin React dependency to 18.2.0 to avoid mismatches. ([#2051](https://github.com/Shopify/hydrogen/pull/2051)) by [@frandiox](https://github.com/frandiox)
2348
+
2349
+ - Updated dependencies [[`9c36c8a5`](https://github.com/Shopify/hydrogen/commit/9c36c8a566b1ae2ceac4846c4c9fe4f63f6f4ab3)]:
2350
+ - @shopify/cli-hydrogen@8.0.2
2351
+
2352
+ ## 1.0.8
2353
+
2354
+ ### Patch Changes
2355
+
2356
+ - Stop inlining the favicon in base64 to avoid issues with the Content-Security-Policy. In `vite.config.js`: ([#2006](https://github.com/Shopify/hydrogen/pull/2006)) by [@frandiox](https://github.com/frandiox)
2357
+
2358
+ ```diff
2359
+ export default defineConfig({
2360
+ plugins: [
2361
+ ...
2362
+ ],
2363
+ + build: {
2364
+ + assetsInlineLimit: 0,
2365
+ + },
2366
+ });
2367
+ ```
2368
+
2369
+ - To improve HMR in Vite, move the `useRootLoaderData` function from `app/root.tsx` to a separate file like `app/lib/root-data.ts`. This change avoids circular imports: ([#2014](https://github.com/Shopify/hydrogen/pull/2014)) by [@frandiox](https://github.com/frandiox)
2370
+
2371
+ ```tsx
2372
+ // app/lib/root-data.ts
2373
+ import {useMatches} from '@remix-run/react';
2374
+ import type {SerializeFrom} from '@shopify/remix-oxygen';
2375
+ import type {loader} from '~/root';
2376
+
2377
+ /**
2378
+ * Access the result of the root loader from a React component.
2379
+ */
2380
+ export const useRootLoaderData = () => {
2381
+ const [root] = useMatches();
2382
+ return root?.data as SerializeFrom<typeof loader>;
2383
+ };
2384
+ ```
2385
+
2386
+ Import this hook from `~/lib/root-data` instead of `~/root` in your components.
2387
+
2388
+ - Updated dependencies [[`b4dfda32`](https://github.com/Shopify/hydrogen/commit/b4dfda320ca52855b2d4493a4306d15a883ca843), [`ffa57bdb`](https://github.com/Shopify/hydrogen/commit/ffa57bdbcdf51e03d565736f9388b5bb4f46292c), [`ac4e1670`](https://github.com/Shopify/hydrogen/commit/ac4e1670f0361a2cd2c6827e4162bbbee0ca37f3), [`0af624d5`](https://github.com/Shopify/hydrogen/commit/0af624d51afc7250db889ba5e736c85a6070c8b2), [`9723eaf3`](https://github.com/Shopify/hydrogen/commit/9723eaf3e5a42c30e657d1cadb123ed775d620e4), [`e842f68c`](https://github.com/Shopify/hydrogen/commit/e842f68c8e879d4c54e0730f3cb55214a760d7f5)]:
2389
+ - @shopify/cli-hydrogen@8.0.1
2390
+ - @shopify/hydrogen@2024.4.1
2391
+
2392
+ ## 1.0.7
2393
+
2394
+ ### Patch Changes
2395
+
2396
+ - Update internal libraries for parsing `.env` files. ([#1946](https://github.com/Shopify/hydrogen/pull/1946)) by [@aswamy](https://github.com/aswamy)
2397
+
2398
+ Please update the `@shopify/cli` dependency in your app to avoid duplicated subdependencies:
2399
+
2400
+ ```diff
2401
+ "dependencies": {
2402
+ - "@shopify/cli": "3.56.3",
2403
+ + "@shopify/cli": "3.58.0",
2404
+ }
2405
+ ```
2406
+
2407
+ - Add Adds magic Catalog route ([#1967](https://github.com/Shopify/hydrogen/pull/1967)) by [@juanpprieto](https://github.com/juanpprieto)
2408
+
2409
+ - Update Vite plugin imports, and how their options are passed to Remix: ([#1935](https://github.com/Shopify/hydrogen/pull/1935)) by [@frandiox](https://github.com/frandiox)
2410
+
2411
+ ```diff
2412
+ -import {hydrogen, oxygen} from '@shopify/cli-hydrogen/experimental-vite';
2413
+ +import {hydrogen} from '@shopify/hydrogen/vite';
2414
+ +import {oxygen} from '@shopify/mini-oxygen/vite';
2415
+ import {vitePlugin as remix} from '@remix-run/dev';
2416
+
2417
+ export default defineConfig({
2418
+ hydrogen(),
2419
+ oxygen(),
2420
+ remix({
2421
+ - buildDirectory: 'dist',
2422
+ + presets: [hydrogen.preset()],
2423
+ future: {
2424
+ ```
2425
+
2426
+ - Add `@shopify/mini-oxygen` as a dev dependency for local development: ([#1891](https://github.com/Shopify/hydrogen/pull/1891)) by [@frandiox](https://github.com/frandiox)
2427
+
2428
+ ```diff
2429
+ "devDependencies": {
2430
+ "@remix-run/dev": "^2.8.0",
2431
+ "@remix-run/eslint-config": "^2.8.0",
2432
+ + "@shopify/mini-oxygen": "^3.0.0",
2433
+ "@shopify/oxygen-workers-types": "^4.0.0",
2434
+ ...
2435
+ },
2436
+ ```
2437
+
2438
+ - Add the `customer-account push` command to the Hydrogen CLI. This allows you to push the current `--dev-origin` URL to the Shopify admin to enable secure connection to the Customer Account API for local development. ([#1804](https://github.com/Shopify/hydrogen/pull/1804)) by [@michenly](https://github.com/michenly)
2439
+
2440
+ - Fix types returned by the `session` object. ([#1869](https://github.com/Shopify/hydrogen/pull/1869)) by [@frandiox](https://github.com/frandiox)
2441
+
2442
+ In `remix.env.d.ts` or `env.d.ts`, add the following types:
2443
+
2444
+ ```diff
2445
+ import type {
2446
+ // ...
2447
+ HydrogenCart,
2448
+ + HydrogenSessionData,
2449
+ } from '@shopify/hydrogen';
2450
+
2451
+ // ...
2452
+
2453
+ declare module '@shopify/remix-oxygen' {
2454
+ // ...
2455
+
2456
+ + interface SessionData extends HydrogenSessionData {}
2457
+ }
2458
+ ```
2459
+
2460
+ - Codegen dependencies must be now listed explicitly in `package.json`: ([#1962](https://github.com/Shopify/hydrogen/pull/1962)) by [@frandiox](https://github.com/frandiox)
2461
+
2462
+ ```diff
2463
+ {
2464
+ "devDependencies": {
2465
+ + "@graphql-codegen/cli": "5.0.2",
2466
+ "@remix-run/dev": "^2.8.0",
2467
+ "@remix-run/eslint-config": "^2.8.0",
2468
+ + "@shopify/hydrogen-codegen": "^0.3.0",
2469
+ "@shopify/mini-oxygen": "^2.2.5",
2470
+ "@shopify/oxygen-workers-types": "^4.0.0",
2471
+ ...
2472
+ }
2473
+ }
2474
+ ```
2475
+
2476
+ - Updated dependencies [[`4eaec272`](https://github.com/Shopify/hydrogen/commit/4eaec272696f1a718aa7cab1070a54385ebc3686), [`14bb5df1`](https://github.com/Shopify/hydrogen/commit/14bb5df1c1513a7991183d34e72220cb2b139cf5), [`646b78d4`](https://github.com/Shopify/hydrogen/commit/646b78d4bc26310121b16000ed4d1c5d5e63957d), [`87072950`](https://github.com/Shopify/hydrogen/commit/870729505f7eb1f1c709799dd036ad02fd94be95), [`5f1295fe`](https://github.com/Shopify/hydrogen/commit/5f1295fe60b86396f364fefef339248a444c988a), [`3c8a7313`](https://github.com/Shopify/hydrogen/commit/3c8a7313cafb0ca21bbca19ac0b3f8ef4ab12655), [`ca1dcbb7`](https://github.com/Shopify/hydrogen/commit/ca1dcbb7d69c458006e25892c86c4478d394a428), [`11879b17`](https://github.com/Shopify/hydrogen/commit/11879b175d78e3326de090a56a044d1e55d0bae8), [`f4d6e5b0`](https://github.com/Shopify/hydrogen/commit/f4d6e5b0244392a7c13b9fa51c5046fd103c3e4f), [`788d86b3`](https://github.com/Shopify/hydrogen/commit/788d86b3a737bff53b4ec3aa9667458b2d45ade7), [`ebaf5529`](https://github.com/Shopify/hydrogen/commit/ebaf5529287b24a70b3146444b18f95b64f9f336), [`da95bb1c`](https://github.com/Shopify/hydrogen/commit/da95bb1c8c644f450053ce649b40dc380e7375dc), [`5bb43304`](https://github.com/Shopify/hydrogen/commit/5bb43304c08427786cfd4f2529e59bd38f593252), [`140e4768`](https://github.com/Shopify/hydrogen/commit/140e4768c880aaed4ba95b1d4c707df6963e011c), [`062d6be7`](https://github.com/Shopify/hydrogen/commit/062d6be7e031c388498ec3d359de51a4bfdfdfd8), [`b3323e59`](https://github.com/Shopify/hydrogen/commit/b3323e59a4381647f1df797c5dc54793f6e0a29a), [`ab0df5a5`](https://github.com/Shopify/hydrogen/commit/ab0df5a52bc587515880ae26f4edd18ba2be83cd), [`ebaf5529`](https://github.com/Shopify/hydrogen/commit/ebaf5529287b24a70b3146444b18f95b64f9f336), [`ebaf5529`](https://github.com/Shopify/hydrogen/commit/ebaf5529287b24a70b3146444b18f95b64f9f336), [`9e899218`](https://github.com/Shopify/hydrogen/commit/9e8992181ce7d27548d35f98b5a4f78b80795ce8), [`a209019f`](https://github.com/Shopify/hydrogen/commit/a209019f722ece4b65f8d5f37c8018c949956b1e), [`d007b7bc`](https://github.com/Shopify/hydrogen/commit/d007b7bc6f6c36e984d937108230ecc7c202fa42), [`a5511cd7`](https://github.com/Shopify/hydrogen/commit/a5511cd7bf9b0f0c4ef0e52cd72418f78c04785b), [`4afedb4d`](https://github.com/Shopify/hydrogen/commit/4afedb4d7202715df9a153e877e8eb281cc3e928), [`34fbae23`](https://github.com/Shopify/hydrogen/commit/34fbae23999eefbd1af1dff44816a52813d75b44), [`e3baaba5`](https://github.com/Shopify/hydrogen/commit/e3baaba54c701a48923ab3fe8078278f2db2c53f), [`99d72f7a`](https://github.com/Shopify/hydrogen/commit/99d72f7afc354abb66ed0e4ffb020bede2781286), [`9351f9f5`](https://github.com/Shopify/hydrogen/commit/9351f9f564267124bcbf986f5550a542c4bf1e30)]:
2477
+ - @shopify/cli-hydrogen@8.0.0
2478
+ - @shopify/hydrogen@2024.4.0
2479
+ - @shopify/remix-oxygen@2.0.4
2480
+
2481
+ ## 1.0.6
2482
+
2483
+ ### Patch Changes
2484
+
2485
+ - Improve performance of predictive search: ([#1823](https://github.com/Shopify/hydrogen/pull/1823)) by [@frandiox](https://github.com/frandiox)
2486
+ - Change the request to be GET instead of POST to avoid Remix route revalidations.
2487
+ - Add Cache-Control headers to the response to get quicker results when typing.
2488
+
2489
+ Aside from that, it now shows a loading state when fetching the results instead of "No results found.".
2490
+
2491
+ - Updated dependencies [[`351b3c1b`](https://github.com/Shopify/hydrogen/commit/351b3c1b7768870793ff072ba91426107ba0180c), [`5060cf57`](https://github.com/Shopify/hydrogen/commit/5060cf57f69d8391b425b54acaa487af1f7405ae), [`2888014e`](https://github.com/Shopify/hydrogen/commit/2888014e54fab72c150e9eca55df3c6dd789503e)]:
2492
+ - @shopify/hydrogen@2024.1.4
2493
+ - @shopify/cli-hydrogen@7.1.2
2494
+
2495
+ ## 1.0.5
2496
+
2497
+ ### Patch Changes
2498
+
2499
+ - Update the `@shopify/cli` dependency: ([#1786](https://github.com/Shopify/hydrogen/pull/1786)) by [@frandiox](https://github.com/frandiox)
2500
+
2501
+ ```diff
2502
+ - "@shopify/cli": "3.52.0",
2503
+ + "@shopify/cli": "3.56.3",
2504
+ ```
2505
+
2506
+ - Update Remix and associated packages to 2.8.0. ([#1781](https://github.com/Shopify/hydrogen/pull/1781)) by [@frandiox](https://github.com/frandiox)
2507
+
2508
+ ```diff
2509
+ "dependencies": {
2510
+ - "@remix-run/react": "^2.6.0",
2511
+ - "@remix-run/server-runtime": "^2.6.0",
2512
+ + "@remix-run/react": "^2.8.0",
2513
+ + "@remix-run/server-runtime": "^2.8.0",
2514
+ //...
2515
+ },
2516
+ "devDependencies": {
2517
+ - "@remix-run/dev": "^2.6.0",
2518
+ - "@remix-run/eslint-config": "^2.6.0",
2519
+ + "@remix-run/dev": "^2.8.0",
2520
+ + "@remix-run/eslint-config": "^2.8.0",
2521
+ //...
2522
+ },
2523
+ ```
2524
+
2525
+ - Updated dependencies [[`ced1d4cb`](https://github.com/Shopify/hydrogen/commit/ced1d4cb5b1eeeb4303449eb1d60aac44f33480e), [`fc013401`](https://github.com/Shopify/hydrogen/commit/fc013401c5727948b602c9c6b6963a2df21cbd38), [`e641255e`](https://github.com/Shopify/hydrogen/commit/e641255eccc5783b41c8fabbc88313a610f539d0), [`d7e04cb6`](https://github.com/Shopify/hydrogen/commit/d7e04cb6a33d40ea86fa8ac2712d7a5ea785de2d), [`eedd9c49`](https://github.com/Shopify/hydrogen/commit/eedd9c497b36aba47a641cecbc710e18f5b14e46)]:
2526
+ - @shopify/cli-hydrogen@7.1.1
2527
+ - @shopify/hydrogen@2024.1.3
2528
+
2529
+ ## 1.0.4
2530
+
2531
+ ### Patch Changes
2532
+
2533
+ - This is an important fix to a bug with 404 routes and path-based i18n projects where some unknown routes would not properly render a 404. This fixes all new projects, but to fix existing projects, add a `($locale).tsx` route with the following contents: ([#1732](https://github.com/Shopify/hydrogen/pull/1732)) by [@blittle](https://github.com/blittle)
2534
+
2535
+ ```ts
2536
+ import {type LoaderFunctionArgs} from '@remix-run/server-runtime';
2537
+
2538
+ export async function loader({params, context}: LoaderFunctionArgs) {
2539
+ const {language, country} = context.storefront.i18n;
2540
+
2541
+ if (
2542
+ params.locale &&
2543
+ params.locale.toLowerCase() !== `${language}-${country}`.toLowerCase()
2544
+ ) {
2545
+ // If the locale URL param is defined, yet we still are still at the default locale
2546
+ // then the the locale param must be invalid, send to the 404 page
2547
+ throw new Response(null, {status: 404});
2548
+ }
2549
+
2550
+ return null;
2551
+ }
2552
+ ```
2553
+
2554
+ - Add defensive null checks to the default cart implementation in the starter template ([#1746](https://github.com/Shopify/hydrogen/pull/1746)) by [@blittle](https://github.com/blittle)
2555
+
2556
+ - 🐛 Fix issue where customer login does not persist to checkout ([#1719](https://github.com/Shopify/hydrogen/pull/1719)) by [@michenly](https://github.com/michenly)
2557
+
2558
+ ✨ Add `customerAccount` option to `createCartHandler`. Where a `?logged_in=true` will be added to the checkoutUrl for cart query if a customer is logged in.
2559
+
2560
+ - Updated dependencies [[`faeba9f8`](https://github.com/Shopify/hydrogen/commit/faeba9f8947d6b9420b33274a0f39b62418ff2e5), [`6d585026`](https://github.com/Shopify/hydrogen/commit/6d585026623204e99d54a5f2efa3d1c74f690bb6), [`fcecfb23`](https://github.com/Shopify/hydrogen/commit/fcecfb2307210b9d73a7cc90ba865508937217ba), [`28864d6f`](https://github.com/Shopify/hydrogen/commit/28864d6ffbb19b62a5fb8f4c9bbe27568de62411), [`c0ec7714`](https://github.com/Shopify/hydrogen/commit/c0ec77141fb1d7a713d91219b8777bc541780ae8), [`226cf478`](https://github.com/Shopify/hydrogen/commit/226cf478a5bdef1cca33fe8f69832ae0e557d9d9), [`06d9fd91`](https://github.com/Shopify/hydrogen/commit/06d9fd91140bd52a8ee41a20bc114ce2e7fb67dc)]:
2561
+ - @shopify/cli-hydrogen@7.1.0
2562
+ - @shopify/hydrogen@2024.1.2
2563
+
2564
+ ## 1.0.3
2565
+
2566
+ ### Patch Changes
2567
+
2568
+ - ♻️ `CustomerClient` type is deprecated and replaced by `CustomerAccount` ([#1692](https://github.com/Shopify/hydrogen/pull/1692)) by [@michenly](https://github.com/michenly)
2569
+
2570
+ - Updated dependencies [[`02798786`](https://github.com/Shopify/hydrogen/commit/02798786bf8ae5c53f6430723a86d62b8e94d120), [`52b15df4`](https://github.com/Shopify/hydrogen/commit/52b15df457ce723bbc83ad594ded73a7b06447d6), [`a2664362`](https://github.com/Shopify/hydrogen/commit/a2664362a7d89b34835553a9b0eb7af55ca70ae4), [`eee5d927`](https://github.com/Shopify/hydrogen/commit/eee5d9274b72404dfb0ffef30d5503fd553be5fe), [`c7b2017f`](https://github.com/Shopify/hydrogen/commit/c7b2017f11a2cb4d280dfd8f170e65a908b9ea02), [`06320ee4`](https://github.com/Shopify/hydrogen/commit/06320ee48b94dbfece945461031a252f454fd0a3)]:
2571
+ - @shopify/hydrogen@2024.1.1
2572
+ - @shopify/cli-hydrogen@7.0.1
2573
+
2574
+ ## 1.0.2
2575
+
2576
+ ### Patch Changes
2577
+
2578
+ - Use new parameters introduced in Storefront API v2024-01 to fix redirection to the product's default variant when there are unknown query params in the URL. ([#1642](https://github.com/Shopify/hydrogen/pull/1642)) by [@wizardlyhel](https://github.com/wizardlyhel)
2579
+
2580
+ ```diff
2581
+ - selectedVariant: variantBySelectedOptions(selectedOptions: $selectedOptions) {
2582
+ + selectedVariant: variantBySelectedOptions(selectedOptions: $selectedOptions, ignoreUnknownOptions: true, caseInsensitiveMatch: true) {
2583
+ ...ProductVariant
2584
+ }
2585
+ ```
2586
+
2587
+ - Update the GraphQL config in `.graphqlrc.yml` to use the more modern `projects` structure: ([#1577](https://github.com/Shopify/hydrogen/pull/1577)) by [@frandiox](https://github.com/frandiox)
2588
+
2589
+ ```diff
2590
+ -schema: node_modules/@shopify/hydrogen/storefront.schema.json
2591
+ +projects:
2592
+ + default:
2593
+ + schema: 'node_modules/@shopify/hydrogen/storefront.schema.json'
2594
+ ```
2595
+
2596
+ This allows you to add additional projects to the GraphQL config, such as third party CMS schemas.
2597
+
2598
+ Also, you can modify the document paths used for the Storefront API queries. This is useful if you have a large codebase and want to exclude certain files from being used for codegen or other GraphQL utilities:
2599
+
2600
+ ```yaml
2601
+ projects:
2602
+ default:
2603
+ schema: 'node_modules/@shopify/hydrogen/storefront.schema.json'
2604
+ documents:
2605
+ - '!*.d.ts'
2606
+ - '*.{ts,tsx,js,jsx}'
2607
+ - 'app/**/*.{ts,tsx,js,jsx}'
2608
+ ```
2609
+
2610
+ - Improve resiliency of `HydrogenSession` ([#1583](https://github.com/Shopify/hydrogen/pull/1583)) by [@blittle](https://github.com/blittle)
2611
+
2612
+ - Update `@shopify/cli` dependency in `package.json`: ([#1579](https://github.com/Shopify/hydrogen/pull/1579)) by [@frandiox](https://github.com/frandiox)
2613
+
2614
+ ```diff
2615
+ - "@shopify/cli": "3.51.0",
2616
+ + "@shopify/cli": "3.52.0",
2617
+ ```
2618
+
2619
+ - - Update example and template Remix versions to `^2.5.1` ([#1639](https://github.com/Shopify/hydrogen/pull/1639)) by [@wizardlyhel](https://github.com/wizardlyhel)
2620
+
2621
+ - Enable Remix future flags:
2622
+ - [`v3_fetcherPersist`](https://remix.run/docs/en/main/hooks/use-fetchers#additional-resources)
2623
+ - [`v3_relativeSplatpath`](https://remix.run/docs/en/main/hooks/use-resolved-path#splat-paths)
2624
+
2625
+ - Updated dependencies [[`810f48cf`](https://github.com/Shopify/hydrogen/commit/810f48cf5d55f0cfcac6e01fe481db8c76e77cd2), [`8c477cb5`](https://github.com/Shopify/hydrogen/commit/8c477cb565c3e018bf4e13bad01804c21611fb8a), [`42ac4138`](https://github.com/Shopify/hydrogen/commit/42ac4138553c7e1a438b075c4f9cb781edffebc4), [`0241b7d2`](https://github.com/Shopify/hydrogen/commit/0241b7d2dcb887d259ce9033aca356d391bc07df), [`6a897586`](https://github.com/Shopify/hydrogen/commit/6a897586bd0908db90736921d11e4b6bdf29c912), [`0ff63bed`](https://github.com/Shopify/hydrogen/commit/0ff63bed840f5b8a5eb9968b67bd9a5a57099253), [`6bc1d61c`](https://github.com/Shopify/hydrogen/commit/6bc1d61c17a9c9be13f52338d2ab940e64e73495), [`eb0f4bcc`](https://github.com/Shopify/hydrogen/commit/eb0f4bccb57966a00ecb2b88d17dd694599da340), [`400bfee6`](https://github.com/Shopify/hydrogen/commit/400bfee6836a51c6ab5e4804e8b1e9ad48856dcb), [`a69c21ca`](https://github.com/Shopify/hydrogen/commit/a69c21caa15dfedb88afd50f262f17bf86f74836), [`970073e7`](https://github.com/Shopify/hydrogen/commit/970073e78258880505e0de563136b5379d5d24af), [`772118ca`](https://github.com/Shopify/hydrogen/commit/772118ca6aefbd47841fffc6ce42856c2dc779bd), [`335375a6`](https://github.com/Shopify/hydrogen/commit/335375a6b1a512f70e169a82bc87a8392dc8c92c), [`335371ce`](https://github.com/Shopify/hydrogen/commit/335371ceb6e1bd5aebb6104f131d3f22798a245f), [`94509b75`](https://github.com/Shopify/hydrogen/commit/94509b750afefd686971198ed86277e2c70f3176), [`36d6fa2c`](https://github.com/Shopify/hydrogen/commit/36d6fa2c4fa54ff79f06ef17aa41f60478977bc0), [`3e7b6e8a`](https://github.com/Shopify/hydrogen/commit/3e7b6e8a3bf66bad7fc0f9c224f1c163dbe3e288), [`cce65795`](https://github.com/Shopify/hydrogen/commit/cce6579580f849bec9a28cf575f7130ba3627f6b), [`9e3d88d4`](https://github.com/Shopify/hydrogen/commit/9e3d88d498efaa20fe23de9837e0f444180bc787), [`ca1161b2`](https://github.com/Shopify/hydrogen/commit/ca1161b29ad7b4d0838953782fb114d5fe82193a), [`92840e51`](https://github.com/Shopify/hydrogen/commit/92840e51820e5c7822f731affd3f591c0099be10), [`952fedf2`](https://github.com/Shopify/hydrogen/commit/952fedf27b869164550954d1c15f53b32ec02675), [`1bc053c9`](https://github.com/Shopify/hydrogen/commit/1bc053c94ba1be14ddc28be9eb70be7219b295d1)]:
2626
+ - @shopify/hydrogen@2024.1.0
2627
+ - @shopify/cli-hydrogen@7.0.0
2628
+ - @shopify/remix-oxygen@2.0.3
2629
+
2630
+ ## 1.0.1
2631
+
2632
+ ### Patch Changes
2633
+
2634
+ - Sync up environment variable names across all example & type files. ([#1542](https://github.com/Shopify/hydrogen/pull/1542)) by [@michenly](https://github.com/michenly)
2635
+
2636
+ - Remove error boundary from robots.txt file in the Skeleton template ([#1492](https://github.com/Shopify/hydrogen/pull/1492)) by [@andrewcohen](https://github.com/andrewcohen)
2637
+
2638
+ - Use the worker runtime by default when running the `dev` or `preview` commands. ([#1525](https://github.com/Shopify/hydrogen/pull/1525)) by [@frandiox](https://github.com/frandiox)
2639
+
2640
+ Enable it in your project by adding the `--worker` flag to your package.json scripts:
2641
+
2642
+ ```diff
2643
+ "scripts": {
2644
+ "build": "shopify hydrogen build",
2645
+ - "dev": "shopify hydrogen dev --codegen",
2646
+ + "dev": "shopify hydrogen dev --worker --codegen",
2647
+ - "preview": "npm run build && shopify hydrogen preview",
2648
+ + "preview": "npm run build && shopify hydrogen preview --worker",
2649
+ ...
2650
+ }
2651
+ ```
2652
+
2653
+ - Update to the latest version of `@shopify/oxygen-workers-types`. ([#1494](https://github.com/Shopify/hydrogen/pull/1494)) by [@frandiox](https://github.com/frandiox)
2654
+
2655
+ In TypeScript projects, when updating to the latest `@shopify/remix-oxygen` adapter release, you should also update to the latest version of `@shopify/oxygen-workers-types`:
2656
+
2657
+ ```diff
2658
+ "devDependencies": {
2659
+ "@remix-run/dev": "2.1.0",
2660
+ "@remix-run/eslint-config": "2.1.0",
2661
+ - "@shopify/oxygen-workers-types": "^3.17.3",
2662
+ + "@shopify/oxygen-workers-types": "^4.0.0",
2663
+ "@shopify/prettier-config": "^1.1.2",
2664
+ ...
2665
+ },
2666
+ ```
2667
+
2668
+ - Update internal dependencies for bug resolution. ([#1496](https://github.com/Shopify/hydrogen/pull/1496)) by [@vincentezw](https://github.com/vincentezw)
2669
+
2670
+ Update your `@shopify/cli` dependency to avoid duplicated sub-dependencies:
2671
+
2672
+ ```diff
2673
+ "dependencies": {
2674
+ - "@shopify/cli": "3.50.2",
2675
+ + "@shopify/cli": "3.51.0",
2676
+ }
2677
+ ```
2678
+
2679
+ - Update all Node.js dependencies to version 18. (Not a breaking change, since Node.js 18 is already required by Remix v2.) ([#1543](https://github.com/Shopify/hydrogen/pull/1543)) by [@michenly](https://github.com/michenly)
2680
+
2681
+ - 🐛 fix undefined menu error ([#1533](https://github.com/Shopify/hydrogen/pull/1533)) by [@michenly](https://github.com/michenly)
2682
+
2683
+ - Add `@remix-run/server-runtime` dependency. ([#1489](https://github.com/Shopify/hydrogen/pull/1489)) by [@frandiox](https://github.com/frandiox)
2684
+
2685
+ Since Remix is now a peer dependency of `@shopify/remix-oxygen`, you need to add `@remix-run/server-runtime` to your dependencies, with the same version as the rest of your Remix dependencies.
2686
+
2687
+ ```diff
2688
+ "dependencies": {
2689
+ "@remix-run/react": "2.1.0"
2690
+ + "@remix-run/server-runtime": "2.1.0"
2691
+ ...
2692
+ }
2693
+ ```
2694
+
2695
+ - Updated dependencies [[`b2a350a7`](https://github.com/Shopify/hydrogen/commit/b2a350a754ea2d29bc267c260dc298a02f8f4470), [`9b4f4534`](https://github.com/Shopify/hydrogen/commit/9b4f453407338874bd8f1a1f619b607670e021d0), [`74ea1dba`](https://github.com/Shopify/hydrogen/commit/74ea1dba9af37a146882df7ed9674be5659862b5), [`2be9ce82`](https://github.com/Shopify/hydrogen/commit/2be9ce82fd4a5121f1772bbb7349e96ed530e84e), [`a9b8bcde`](https://github.com/Shopify/hydrogen/commit/a9b8bcde96c22cedef7d87631d429199810b4a7a), [`bca112ed`](https://github.com/Shopify/hydrogen/commit/bca112ed7db49e533fe49898b663fa0dd318e6ba), [`848c6260`](https://github.com/Shopify/hydrogen/commit/848c6260a2db3a9cb0c86351f0f7128f61e028f0), [`d53b4ed7`](https://github.com/Shopify/hydrogen/commit/d53b4ed752eb0530622a666ea7dcf4b40239cafa), [`961fd8c6`](https://github.com/Shopify/hydrogen/commit/961fd8c630727784f77b9f693d2e8ff8601969fc), [`2bff9fc7`](https://github.com/Shopify/hydrogen/commit/2bff9fc75916fa95f9a9279d069408fb7a33755c), [`c8e8f6fd`](https://github.com/Shopify/hydrogen/commit/c8e8f6fd233e52cf5570b1904af710d6b907aae5), [`8fce70de`](https://github.com/Shopify/hydrogen/commit/8fce70de32bd61ee86a6d895ac43cc1f78f1bf49), [`f90e4d47`](https://github.com/Shopify/hydrogen/commit/f90e4d4713c6c1fc1e921a7ecd08e95fe5da1744), [`e8cc49fe`](https://github.com/Shopify/hydrogen/commit/e8cc49feff18f5ee72d5f6965ff2094addc23466)]:
2696
+ - @shopify/cli-hydrogen@6.1.0
2697
+ - @shopify/remix-oxygen@2.0.2
2698
+ - @shopify/hydrogen@2023.10.3
2699
+
2700
+ ## 1.0.0
2701
+
2702
+ ### Major Changes
2703
+
2704
+ - 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)
2705
+ 1. Update the `HeaderMenu` component to accept a `primaryDomainUrl` and include
2706
+ it in the internal url check
2707
+
2708
+ ```diff
2709
+ // app/components/Header.tsx
2710
+
2711
+ + import type {HeaderQuery} from 'storefrontapi.generated';
2712
+
2713
+ export function HeaderMenu({
2714
+ menu,
2715
+ + primaryDomainUrl,
2716
+ viewport,
2717
+ }: {
2718
+ menu: HeaderProps['header']['menu'];
2719
+ + primaryDomainUrl: HeaderQuery['shop']['primaryDomain']['url'];
2720
+ viewport: Viewport;
2721
+ }) {
2722
+
2723
+ // ...code
2724
+
2725
+ // if the url is internal, we strip the domain
2726
+ const url =
2727
+ item.url.includes('myshopify.com') ||
2728
+ item.url.includes(publicStoreDomain) ||
2729
+ + item.url.includes(primaryDomainUrl)
2730
+ ? new URL(item.url).pathname
2731
+ : item.url;
2732
+
2733
+ // ...code
2734
+
2735
+ }
2736
+ ```
2737
+
2738
+ 2. Update the `FooterMenu` component to accept a `primaryDomainUrl` prop and include
2739
+ it in the internal url check
2740
+
2741
+ ```diff
2742
+ // app/components/Footer.tsx
2743
+
2744
+ - import type {FooterQuery} from 'storefrontapi.generated';
2745
+ + import type {FooterQuery, HeaderQuery} from 'storefrontapi.generated';
2746
+
2747
+ function FooterMenu({
2748
+ menu,
2749
+ + primaryDomainUrl,
2750
+ }: {
2751
+ menu: FooterQuery['menu'];
2752
+ + primaryDomainUrl: HeaderQuery['shop']['primaryDomain']['url'];
2753
+ }) {
2754
+ // code...
2755
+
2756
+ // if the url is internal, we strip the domain
2757
+ const url =
2758
+ item.url.includes('myshopify.com') ||
2759
+ item.url.includes(publicStoreDomain) ||
2760
+ + item.url.includes(primaryDomainUrl)
2761
+ ? new URL(item.url).pathname
2762
+ : item.url;
2763
+
2764
+ // ...code
2765
+
2766
+ );
2767
+ }
2768
+ ```
2769
+
2770
+ 3. Update the `Footer` component to accept a `shop` prop
2771
+
2772
+ ```diff
2773
+ export function Footer({
2774
+ menu,
2775
+ + shop,
2776
+ }: FooterQuery & {shop: HeaderQuery['shop']}) {
2777
+ return (
2778
+ <footer className="footer">
2779
+ - <FooterMenu menu={menu} />
2780
+ + <FooterMenu menu={menu} primaryDomainUrl={shop.primaryDomain.url} />
2781
+ </footer>
2782
+ );
2783
+ }
2784
+ ```
2785
+
2786
+ 4. Update `Layout.tsx` to pass the `shop` prop
2787
+
2788
+ ```diff
2789
+ export function Layout({
2790
+ cart,
2791
+ children = null,
2792
+ footer,
2793
+ header,
2794
+ isLoggedIn,
2795
+ }: LayoutProps) {
2796
+ return (
2797
+ <>
2798
+ <CartAside cart={cart} />
2799
+ <SearchAside />
2800
+ <MobileMenuAside menu={header.menu} shop={header.shop} />
2801
+ <Header header={header} cart={cart} isLoggedIn={isLoggedIn} />
2802
+ <main>{children}</main>
2803
+ <Suspense>
2804
+ <Await resolve={footer}>
2805
+ - {(footer) => <Footer menu={footer.menu} />}
2806
+ + {(footer) => <Footer menu={footer.menu} shop={header.shop} />}
2807
+ </Await>
2808
+ </Suspense>
2809
+ </>
2810
+ );
2811
+ }
2812
+ ```
2813
+
2814
+ ### Patch Changes
2815
+
2816
+ - If you are calling `useMatches()` in different places of your app to access the data returned by the root loader, you may want to update it to the following pattern to enhance types: ([#1289](https://github.com/Shopify/hydrogen/pull/1289)) by [@frandiox](https://github.com/frandiox)
2817
+
2818
+ ```ts
2819
+ // root.tsx
2820
+
2821
+ import {useMatches} from '@remix-run/react';
2822
+ import {type SerializeFrom} from '@shopify/remix-oxygen';
2823
+
2824
+ export const useRootLoaderData = () => {
2825
+ const [root] = useMatches();
2826
+ return root?.data as SerializeFrom<typeof loader>;
2827
+ };
2828
+
2829
+ export function loader(context) {
2830
+ // ...
2831
+ }
2832
+ ```
2833
+
2834
+ This way, you can import `useRootLoaderData()` anywhere in your app and get the correct type for the data returned by the root loader.
2835
+
2836
+ - Updated dependencies [[`81400439`](https://github.com/Shopify/hydrogen/commit/814004397c1d17ef0a53a425ed28a42cf67765cf), [`a6f397b6`](https://github.com/Shopify/hydrogen/commit/a6f397b64dc6a0d856cb7961731ee1f86bf80292), [`3464ec04`](https://github.com/Shopify/hydrogen/commit/3464ec04a084e1ceb30ee19874dc1b9171ce2b34), [`7fc088e2`](https://github.com/Shopify/hydrogen/commit/7fc088e21bea47840788cb7c60f873ce1f253128), [`867e0b03`](https://github.com/Shopify/hydrogen/commit/867e0b033fc9eb04b7250baea97d8fd49d26ccca), [`ad45656c`](https://github.com/Shopify/hydrogen/commit/ad45656c5f663cc1a60eab5daab4da1dfd0e6cc3), [`f24e3424`](https://github.com/Shopify/hydrogen/commit/f24e3424c8e2b363b181b71fcbd3e45f696fdd3f), [`66a48573`](https://github.com/Shopify/hydrogen/commit/66a4857387148b6a104df5783314c74aca8aada0), [`0ae7cbe2`](https://github.com/Shopify/hydrogen/commit/0ae7cbe280d8351126e11dc13f35d7277d9b2d86), [`8198c1be`](https://github.com/Shopify/hydrogen/commit/8198c1befdfafb39fbcc88d71f91d21eae252973), [`ad45656c`](https://github.com/Shopify/hydrogen/commit/ad45656c5f663cc1a60eab5daab4da1dfd0e6cc3)]:
2837
+ - @shopify/hydrogen@2023.10.0
2838
+ - @shopify/remix-oxygen@2.0.0
2839
+ - @shopify/cli-hydrogen@6.0.0