@shopify/cli-hydrogen 7.1.2 → 8.0.1

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 (145) hide show
  1. package/dist/commands/hydrogen/build-vite.js +19 -10
  2. package/dist/commands/hydrogen/build.js +10 -2
  3. package/dist/commands/hydrogen/check.js +1 -0
  4. package/dist/commands/hydrogen/codegen.js +1 -0
  5. package/dist/commands/hydrogen/customer-account/push.js +170 -0
  6. package/dist/commands/hydrogen/debug/cpu.js +10 -1
  7. package/dist/commands/hydrogen/deploy.js +110 -36
  8. package/dist/commands/hydrogen/dev-vite.js +128 -59
  9. package/dist/commands/hydrogen/dev.js +108 -51
  10. package/dist/commands/hydrogen/env/list.js +20 -28
  11. package/dist/commands/hydrogen/env/pull.js +29 -19
  12. package/dist/commands/hydrogen/env/{push__unstable.js → push.js} +34 -68
  13. package/dist/commands/hydrogen/generate/route.js +1 -0
  14. package/dist/commands/hydrogen/init.js +39 -21
  15. package/dist/commands/hydrogen/link.js +25 -6
  16. package/dist/commands/hydrogen/list.js +1 -0
  17. package/dist/commands/hydrogen/login.js +1 -0
  18. package/dist/commands/hydrogen/logout.js +1 -0
  19. package/dist/commands/hydrogen/preview.js +31 -16
  20. package/dist/commands/hydrogen/setup/css.js +8 -1
  21. package/dist/commands/hydrogen/setup/markets.js +1 -0
  22. package/dist/commands/hydrogen/setup/vite.js +244 -138
  23. package/dist/commands/hydrogen/setup.js +21 -23
  24. package/dist/commands/hydrogen/shortcut.js +10 -0
  25. package/dist/commands/hydrogen/unlink.js +1 -0
  26. package/dist/commands/hydrogen/upgrade.js +2 -1
  27. package/dist/generator-templates/assets/vite/package.json +3 -4
  28. package/dist/generator-templates/assets/vite/vite.config.js +15 -2
  29. package/dist/generator-templates/starter/CHANGELOG.md +129 -0
  30. package/dist/generator-templates/starter/README.md +3 -44
  31. package/dist/generator-templates/starter/app/components/Footer.tsx +1 -1
  32. package/dist/generator-templates/starter/app/components/Header.tsx +1 -1
  33. package/dist/generator-templates/starter/app/graphql/customer-account/CustomerDetailsQuery.ts +1 -0
  34. package/dist/generator-templates/starter/app/lib/fragments.ts +2 -0
  35. package/dist/generator-templates/starter/app/lib/root-data.ts +11 -0
  36. package/dist/generator-templates/starter/app/root.tsx +4 -20
  37. package/dist/generator-templates/starter/app/routes/account.orders._index.tsx +1 -1
  38. package/dist/generator-templates/starter/app/routes/account.tsx +1 -1
  39. package/dist/generator-templates/starter/app/routes/blogs.$blogHandle._index.tsx +3 -3
  40. package/dist/generator-templates/starter/app/routes/cart.tsx +1 -1
  41. package/dist/generator-templates/starter/app/routes/collections.all.tsx +160 -0
  42. package/dist/generator-templates/starter/app/routes/products.$handle.tsx +1 -2
  43. package/dist/generator-templates/starter/customer-accountapi.generated.d.ts +6 -3
  44. package/dist/generator-templates/starter/{remix.env.d.ts → env.d.ts} +8 -2
  45. package/dist/generator-templates/starter/package.json +14 -9
  46. package/dist/generator-templates/starter/server.ts +2 -1
  47. package/dist/generator-templates/starter/storefrontapi.generated.d.ts +59 -3
  48. package/dist/generator-templates/starter/vite.config.ts +26 -0
  49. package/dist/{commands/hydrogen/init.d.ts → init.d.ts} +11 -4
  50. package/dist/lib/check-lockfile.js +12 -18
  51. package/dist/lib/codegen.js +37 -13
  52. package/dist/lib/common.js +50 -0
  53. package/dist/lib/cpu-profiler.js +4 -1
  54. package/dist/lib/dev-shared.js +99 -0
  55. package/dist/lib/environment-variables.js +51 -30
  56. package/dist/lib/file.js +8 -1
  57. package/dist/lib/flags.js +37 -26
  58. package/dist/lib/get-oxygen-deployment-data.js +10 -17
  59. package/dist/lib/graphql/admin/customer-application-update.js +29 -0
  60. package/dist/lib/graphql/admin/get-oxygen-data.js +1 -0
  61. package/dist/lib/graphql/admin/list-environments.js +1 -0
  62. package/dist/lib/graphql/admin/pull-variables.js +4 -4
  63. package/dist/lib/graphql/admin/test-helper.js +37 -0
  64. package/dist/lib/log.js +86 -13
  65. package/dist/lib/mini-oxygen/common.js +19 -33
  66. package/dist/lib/mini-oxygen/index.js +6 -2
  67. package/dist/lib/mini-oxygen/node.js +43 -31
  68. package/dist/lib/mini-oxygen/workerd.js +72 -165
  69. package/dist/lib/missing-routes.js +1 -1
  70. package/dist/lib/onboarding/common.js +85 -70
  71. package/dist/lib/onboarding/local.js +19 -9
  72. package/dist/lib/onboarding/remote.js +35 -30
  73. package/dist/lib/package-managers.js +24 -0
  74. package/dist/lib/remix-config.js +17 -1
  75. package/dist/lib/render-errors.js +17 -10
  76. package/dist/lib/request-events.js +6 -1
  77. package/dist/lib/setups/i18n/replacers.js +9 -6
  78. package/dist/lib/setups/routes/generate.js +1 -0
  79. package/dist/lib/shell.js +2 -1
  80. package/dist/lib/shopify-config.js +19 -1
  81. package/dist/lib/template-diff.js +36 -15
  82. package/dist/lib/template-downloader.js +35 -5
  83. package/dist/lib/transpile/morph/functions.js +26 -8
  84. package/dist/lib/transpile/morph/typedefs.js +6 -4
  85. package/dist/lib/transpile/project.js +8 -4
  86. package/dist/lib/tunneling.js +44 -0
  87. package/dist/lib/verify-linked-storefront.js +24 -0
  88. package/dist/lib/virtual-routes.js +1 -1
  89. package/dist/lib/vite-config.js +39 -9
  90. package/oclif.manifest.json +704 -508
  91. package/package.json +32 -24
  92. package/dist/commands/hydrogen/deploy.test.js +0 -553
  93. package/dist/commands/hydrogen/env/list.test.js +0 -148
  94. package/dist/commands/hydrogen/env/pull.test.js +0 -207
  95. package/dist/commands/hydrogen/env/push__unstable.test.js +0 -383
  96. package/dist/commands/hydrogen/generate/route.test.js +0 -43
  97. package/dist/commands/hydrogen/init.test.js +0 -641
  98. package/dist/commands/hydrogen/link.test.js +0 -187
  99. package/dist/commands/hydrogen/list.test.js +0 -111
  100. package/dist/commands/hydrogen/setup.test.js +0 -61
  101. package/dist/commands/hydrogen/shortcut.test.js +0 -30
  102. package/dist/commands/hydrogen/unlink.test.js +0 -36
  103. package/dist/commands/hydrogen/upgrade.test.js +0 -786
  104. package/dist/generator-templates/starter/remix.config.js +0 -24
  105. package/dist/lib/auth.test.js +0 -157
  106. package/dist/lib/check-lockfile.test.js +0 -81
  107. package/dist/lib/check-version.test.js +0 -86
  108. package/dist/lib/environment-variables.test.js +0 -149
  109. package/dist/lib/file.test.js +0 -68
  110. package/dist/lib/flags.test.js +0 -43
  111. package/dist/lib/get-oxygen-deployment-data.test.js +0 -120
  112. package/dist/lib/gid.test.js +0 -15
  113. package/dist/lib/graphql/admin/client.test.js +0 -76
  114. package/dist/lib/graphql/admin/create-storefront.test.js +0 -64
  115. package/dist/lib/graphql/admin/link-storefront.test.js +0 -38
  116. package/dist/lib/graphql/admin/list-environments.test.js +0 -44
  117. package/dist/lib/graphql/admin/list-storefronts.test.js +0 -44
  118. package/dist/lib/graphql/admin/pull-variables.test.js +0 -43
  119. package/dist/lib/graphql/business-platform/user-account.test.js +0 -80
  120. package/dist/lib/log.test.js +0 -92
  121. package/dist/lib/mini-oxygen/assets.js +0 -134
  122. package/dist/lib/mini-oxygen/mini-oxygen.test.js +0 -214
  123. package/dist/lib/mini-oxygen/workerd-inspector-logs.js +0 -227
  124. package/dist/lib/mini-oxygen/workerd-inspector-proxy.js +0 -200
  125. package/dist/lib/mini-oxygen/workerd-inspector.js +0 -219
  126. package/dist/lib/missing-routes.test.js +0 -45
  127. package/dist/lib/remix-version-check.test.js +0 -39
  128. package/dist/lib/remix-version-interop.test.js +0 -13
  129. package/dist/lib/setups/i18n/domains.test.js +0 -39
  130. package/dist/lib/setups/i18n/replacers.test.js +0 -261
  131. package/dist/lib/setups/i18n/subdomains.test.js +0 -39
  132. package/dist/lib/setups/i18n/subfolders.test.js +0 -39
  133. package/dist/lib/setups/routes/generate.test.js +0 -296
  134. package/dist/lib/shell.test.js +0 -111
  135. package/dist/lib/shopify-config.test.js +0 -199
  136. package/dist/lib/string.test.js +0 -16
  137. package/dist/lib/virtual-routes.test.js +0 -49
  138. package/dist/lib/vite/hydrogen-middleware.js +0 -82
  139. package/dist/lib/vite/mini-oxygen.js +0 -152
  140. package/dist/lib/vite/plugins.d.ts +0 -27
  141. package/dist/lib/vite/plugins.js +0 -139
  142. package/dist/lib/vite/shared.js +0 -10
  143. package/dist/lib/vite/utils.js +0 -55
  144. package/dist/lib/vite/worker-entry.js +0 -1518
  145. /package/dist/generator-templates/starter/{.eslintrc.js → .eslintrc.cjs} +0 -0
@@ -1,5 +1,134 @@
1
1
  # skeleton
2
2
 
3
+ ## 1.0.8
4
+
5
+ ### Patch Changes
6
+
7
+ - 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)
8
+
9
+ ```diff
10
+ export default defineConfig({
11
+ plugins: [
12
+ ...
13
+ ],
14
+ + build: {
15
+ + assetsInlineLimit: 0,
16
+ + },
17
+ });
18
+ ```
19
+
20
+ - 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)
21
+
22
+ ```tsx
23
+ // app/lib/root-data.ts
24
+ import {useMatches} from '@remix-run/react';
25
+ import type {SerializeFrom} from '@shopify/remix-oxygen';
26
+ import type {loader} from '~/root';
27
+
28
+ /**
29
+ * Access the result of the root loader from a React component.
30
+ */
31
+ export const useRootLoaderData = () => {
32
+ const [root] = useMatches();
33
+ return root?.data as SerializeFrom<typeof loader>;
34
+ };
35
+ ```
36
+
37
+ Import this hook from `~/lib/root-data` instead of `~/root` in your components.
38
+
39
+ - 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)]:
40
+ - @shopify/cli-hydrogen@8.0.1
41
+ - @shopify/hydrogen@2024.4.1
42
+
43
+ ## 1.0.7
44
+
45
+ ### Patch Changes
46
+
47
+ - Update internal libraries for parsing `.env` files. ([#1946](https://github.com/Shopify/hydrogen/pull/1946)) by [@aswamy](https://github.com/aswamy)
48
+
49
+ Please update the `@shopify/cli` dependency in your app to avoid duplicated subdependencies:
50
+
51
+ ```diff
52
+ "dependencies": {
53
+ - "@shopify/cli": "3.56.3",
54
+ + "@shopify/cli": "3.58.0",
55
+ }
56
+ ```
57
+
58
+ - Add Adds magic Catalog route ([#1967](https://github.com/Shopify/hydrogen/pull/1967)) by [@juanpprieto](https://github.com/juanpprieto)
59
+
60
+ - 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)
61
+
62
+ ```diff
63
+ -import {hydrogen, oxygen} from '@shopify/cli-hydrogen/experimental-vite';
64
+ +import {hydrogen} from '@shopify/hydrogen/vite';
65
+ +import {oxygen} from '@shopify/mini-oxygen/vite';
66
+ import {vitePlugin as remix} from '@remix-run/dev';
67
+
68
+ export default defineConfig({
69
+ hydrogen(),
70
+ oxygen(),
71
+ remix({
72
+ - buildDirectory: 'dist',
73
+ + presets: [hydrogen.preset()],
74
+ future: {
75
+ ```
76
+
77
+ - 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)
78
+
79
+ ```diff
80
+ "devDependencies": {
81
+ "@remix-run/dev": "^2.8.0",
82
+ "@remix-run/eslint-config": "^2.8.0",
83
+ + "@shopify/mini-oxygen": "^3.0.0",
84
+ "@shopify/oxygen-workers-types": "^4.0.0",
85
+ ...
86
+ },
87
+ ```
88
+
89
+ - 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)
90
+
91
+ - Fix types returned by the `session` object. ([#1869](https://github.com/Shopify/hydrogen/pull/1869)) by [@frandiox](https://github.com/frandiox)
92
+
93
+ In `remix.env.d.ts` or `env.d.ts`, add the following types:
94
+
95
+ ```diff
96
+ import type {
97
+ // ...
98
+ HydrogenCart,
99
+ + HydrogenSessionData,
100
+ } from '@shopify/hydrogen';
101
+
102
+ // ...
103
+
104
+ declare module '@shopify/remix-oxygen' {
105
+ // ...
106
+
107
+ + interface SessionData extends HydrogenSessionData {}
108
+ }
109
+ ```
110
+
111
+ - Codegen dependencies must be now listed explicitly in `package.json`: ([#1962](https://github.com/Shopify/hydrogen/pull/1962)) by [@frandiox](https://github.com/frandiox)
112
+
113
+ ```diff
114
+ {
115
+ "devDependencies": {
116
+ + "@graphql-codegen/cli": "5.0.2",
117
+ "@remix-run/dev": "^2.8.0",
118
+ "@remix-run/eslint-config": "^2.8.0",
119
+ + "@shopify/hydrogen-codegen": "^0.3.0",
120
+ "@shopify/mini-oxygen": "^2.2.5",
121
+ "@shopify/oxygen-workers-types": "^4.0.0",
122
+ ...
123
+ }
124
+ }
125
+ ```
126
+
127
+ - 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)]:
128
+ - @shopify/cli-hydrogen@8.0.0
129
+ - @shopify/hydrogen@2024.4.0
130
+ - @shopify/remix-oxygen@2.0.4
131
+
3
132
  ## 1.0.6
4
133
 
5
134
  ### Patch Changes
@@ -10,6 +10,7 @@ Hydrogen is Shopify’s stack for headless commerce. Hydrogen is designed to dov
10
10
  - Remix
11
11
  - Hydrogen
12
12
  - Oxygen
13
+ - Vite
13
14
  - Shopify CLI
14
15
  - ESLint
15
16
  - Prettier
@@ -21,7 +22,7 @@ Hydrogen is Shopify’s stack for headless commerce. Hydrogen is designed to dov
21
22
 
22
23
  **Requirements:**
23
24
 
24
- - Node.js version 16.14.0 or higher
25
+ - Node.js version 18.0.0 or higher
25
26
 
26
27
  ```bash
27
28
  npm create @shopify/hydrogen@latest
@@ -41,46 +42,4 @@ npm run dev
41
42
 
42
43
  ## Setup for using Customer Account API (`/account` section)
43
44
 
44
- ### Enabled new Customer Account Experience
45
-
46
- 1. Go to your Shopify admin => Settings => Customer accounts => New customer account
47
-
48
- ### Setup public domain using ngrok
49
-
50
- 1. Setup a [ngrok](https://ngrok.com/) account and add a permanent domain (ie. `https://<your-ngrok-domain>.app`).
51
- 1. Install the [ngrok CLI](https://ngrok.com/download) to use in terminal
52
- 1. Start ngrok using `ngrok http --domain=<your-ngrok-domain>.app 3000`
53
-
54
- > [!IMPORTANT]
55
- > To successfully interact with the Customer Account API routes you will need to use the ngrok domain during development instead of localhost
56
- ### Include public domain in Customer Account API settings
57
-
58
- 1. Go to your Shopify admin => `Hydrogen` or `Headless` app/channel => Customer Account API => Application setup
59
- 1. Edit `Callback URI(s)` to include `https://<your-ngrok-domain>.app/account/authorize`
60
- 1. Edit `Javascript origin(s)` to include your public domain `https://<your-ngrok-domain>.app` or keep it blank
61
- 1. Edit `Logout URI` to include your public domain `https://<your-ngrok-domain>.app` or keep it blank
62
-
63
- ### Add the ngrok domain to the CSP policy
64
-
65
- Modify your `/app/entry.server.tsx` to allow the ngrok domain as a connect-src
66
-
67
- ```diff
68
- - const {nonce, header, NonceProvider} = createContentSecurityPolicy()
69
- + const {nonce, header, NonceProvider} = createContentSecurityPolicy({
70
- + connectSrc: [
71
- + 'wss://<your-ngrok-domain>.app:*', // Your ngrok websocket domain
72
- + ],
73
- + });
74
- ```
75
-
76
- ### Prepare Environment variables
77
-
78
- Run [`npx shopify hydrogen link`](https://shopify.dev/docs/custom-storefronts/hydrogen/cli#link) or [`npx shopify hydrogen env pull`](https://shopify.dev/docs/custom-storefronts/hydrogen/cli#env-pull) to link this app to your own test shop.
79
-
80
- Alternately, the values of the required environment variables "PUBLIC_CUSTOMER_ACCOUNT_API_CLIENT_ID" and "PUBLIC_CUSTOMER_ACCOUNT_API_URL" can be found in customer account api settings in the Hydrogen admin channel.
81
-
82
- > [!IMPORTANT]
83
- > Note that `mock.shop` doesn't supply these variables automatically and your own test shop is required for using Customer Account API
84
-
85
- > [!NOTE]
86
- > B2B features such as contextual pricing is not available in SF API with Customer Account API login. If you require this feature, we suggest using the [legacy-customer-account-flow](https://github.com/Shopify/hydrogen/tree/main/examples/legacy-customer-account-flow). This feature should be available in the Customer Account API in the 2024-04 release.
45
+ Follow step 1 and 2 of <https://shopify.dev/docs/custom-storefronts/building-with-the-customer-account-api/hydrogen#step-1-set-up-a-public-domain-for-local-development>
@@ -1,6 +1,6 @@
1
1
  import {NavLink} from '@remix-run/react';
2
2
  import type {FooterQuery, HeaderQuery} from 'storefrontapi.generated';
3
- import {useRootLoaderData} from '~/root';
3
+ import {useRootLoaderData} from '~/lib/root-data';
4
4
 
5
5
  export function Footer({
6
6
  menu,
@@ -2,7 +2,7 @@ import {Await, NavLink} from '@remix-run/react';
2
2
  import {Suspense} from 'react';
3
3
  import type {HeaderQuery} from 'storefrontapi.generated';
4
4
  import type {LayoutProps} from './Layout';
5
- import {useRootLoaderData} from '~/root';
5
+ import {useRootLoaderData} from '~/lib/root-data';
6
6
 
7
7
  type HeaderProps = Pick<LayoutProps, 'header' | 'cart' | 'isLoggedIn'>;
8
8
 
@@ -1,6 +1,7 @@
1
1
  // NOTE: https://shopify.dev/docs/api/customer/latest/objects/Customer
2
2
  export const CUSTOMER_FRAGMENT = `#graphql
3
3
  fragment Customer on Customer {
4
+ id
4
5
  firstName
5
6
  lastName
6
7
  defaultAddress {
@@ -46,6 +46,7 @@ export const CART_QUERY_FRAGMENT = `#graphql
46
46
  handle
47
47
  title
48
48
  id
49
+ vendor
49
50
  }
50
51
  selectedOptions {
51
52
  name
@@ -55,6 +56,7 @@ export const CART_QUERY_FRAGMENT = `#graphql
55
56
  }
56
57
  }
57
58
  fragment CartApiQuery on Cart {
59
+ updatedAt
58
60
  id
59
61
  checkoutUrl
60
62
  totalQuantity
@@ -0,0 +1,11 @@
1
+ import {useMatches} from '@remix-run/react';
2
+ import type {SerializeFrom} from '@shopify/remix-oxygen';
3
+ import type {loader} from '~/root';
4
+
5
+ /**
6
+ * Access the result of the root loader from a React component.
7
+ */
8
+ export function useRootLoaderData() {
9
+ const [root] = useMatches();
10
+ return root?.data as SerializeFrom<typeof loader>;
11
+ }
@@ -1,16 +1,10 @@
1
1
  import {useNonce} from '@shopify/hydrogen';
2
- import {
3
- defer,
4
- type SerializeFrom,
5
- type LoaderFunctionArgs,
6
- } from '@shopify/remix-oxygen';
2
+ import {defer, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
7
3
  import {
8
4
  Links,
9
5
  Meta,
10
6
  Outlet,
11
7
  Scripts,
12
- LiveReload,
13
- useMatches,
14
8
  useRouteError,
15
9
  useLoaderData,
16
10
  ScrollRestoration,
@@ -18,8 +12,8 @@ import {
18
12
  type ShouldRevalidateFunction,
19
13
  } from '@remix-run/react';
20
14
  import favicon from './assets/favicon.svg';
21
- import resetStyles from './styles/reset.css';
22
- import appStyles from './styles/app.css';
15
+ import resetStyles from './styles/reset.css?url';
16
+ import appStyles from './styles/app.css?url';
23
17
  import {Layout} from '~/components/Layout';
24
18
 
25
19
  /**
@@ -59,14 +53,6 @@ export function links() {
59
53
  ];
60
54
  }
61
55
 
62
- /**
63
- * Access the result of the root loader from a React component.
64
- */
65
- export const useRootLoaderData = () => {
66
- const [root] = useMatches();
67
- return root?.data as SerializeFrom<typeof loader>;
68
- };
69
-
70
56
  export async function loader({context}: LoaderFunctionArgs) {
71
57
  const {storefront, customerAccount, cart} = context;
72
58
  const publicStoreDomain = context.env.PUBLIC_STORE_DOMAIN;
@@ -124,7 +110,6 @@ export default function App() {
124
110
  </Layout>
125
111
  <ScrollRestoration nonce={nonce} />
126
112
  <Scripts nonce={nonce} />
127
- <LiveReload nonce={nonce} />
128
113
  </body>
129
114
  </html>
130
115
  );
@@ -132,7 +117,7 @@ export default function App() {
132
117
 
133
118
  export function ErrorBoundary() {
134
119
  const error = useRouteError();
135
- const rootData = useRootLoaderData();
120
+ const rootData = useLoaderData<typeof loader>();
136
121
  const nonce = useNonce();
137
122
  let errorMessage = 'Unknown error';
138
123
  let errorStatus = 500;
@@ -166,7 +151,6 @@ export function ErrorBoundary() {
166
151
  </Layout>
167
152
  <ScrollRestoration nonce={nonce} />
168
153
  <Scripts nonce={nonce} />
169
- <LiveReload nonce={nonce} />
170
154
  </body>
171
155
  </html>
172
156
  );
@@ -99,7 +99,7 @@ function OrderItem({order}: {order: OrderItemFragment}) {
99
99
  return (
100
100
  <>
101
101
  <fieldset>
102
- <Link to={`/account/orders/${order.id}`}>
102
+ <Link to={`/account/orders/${btoa(order.id)}`}>
103
103
  <strong>#{order.number}</strong>
104
104
  </Link>
105
105
  <p>{new Date(order.processedAt).toDateString()}</p>
@@ -1,4 +1,4 @@
1
- import {json, redirect, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
1
+ import {json, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
2
2
  import {Form, NavLink, Outlet, useLoaderData} from '@remix-run/react';
3
3
  import {CUSTOMER_DETAILS_QUERY} from '~/graphql/customer-account/CustomerDetailsQuery';
4
4
 
@@ -7,11 +7,11 @@ export const meta: MetaFunction<typeof loader> = ({data}) => {
7
7
  return [{title: `Hydrogen | ${data?.blog.title ?? ''} blog`}];
8
8
  };
9
9
 
10
- export const loader = async ({
10
+ export async function loader({
11
11
  request,
12
12
  params,
13
13
  context: {storefront},
14
- }: LoaderFunctionArgs) => {
14
+ }: LoaderFunctionArgs) {
15
15
  const paginationVariables = getPaginationVariables(request, {
16
16
  pageBy: 4,
17
17
  });
@@ -32,7 +32,7 @@ export const loader = async ({
32
32
  }
33
33
 
34
34
  return json({blog});
35
- };
35
+ }
36
36
 
37
37
  export default function Blog() {
38
38
  const {blog} = useLoaderData<typeof loader>();
@@ -4,7 +4,7 @@ import type {CartQueryDataReturn} from '@shopify/hydrogen';
4
4
  import {CartForm} from '@shopify/hydrogen';
5
5
  import {json, type ActionFunctionArgs} from '@shopify/remix-oxygen';
6
6
  import {CartMain} from '~/components/Cart';
7
- import {useRootLoaderData} from '~/root';
7
+ import {useRootLoaderData} from '~/lib/root-data';
8
8
 
9
9
  export const meta: MetaFunction = () => {
10
10
  return [{title: `Hydrogen | Cart`}];
@@ -0,0 +1,160 @@
1
+ import {json, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
2
+ import {useLoaderData, Link, type MetaFunction} from '@remix-run/react';
3
+ import {
4
+ Pagination,
5
+ getPaginationVariables,
6
+ Image,
7
+ Money,
8
+ } from '@shopify/hydrogen';
9
+ import type {ProductItemFragment} from 'storefrontapi.generated';
10
+ import {useVariantUrl} from '~/lib/variants';
11
+
12
+ export const meta: MetaFunction<typeof loader> = () => {
13
+ return [{title: `Hydrogen | Products`}];
14
+ };
15
+
16
+ export async function loader({request, context}: LoaderFunctionArgs) {
17
+ const {storefront} = context;
18
+ const paginationVariables = getPaginationVariables(request, {
19
+ pageBy: 8,
20
+ });
21
+
22
+ const {products} = await storefront.query(CATALOG_QUERY, {
23
+ variables: {...paginationVariables},
24
+ });
25
+
26
+ return json({products});
27
+ }
28
+
29
+ export default function Collection() {
30
+ const {products} = useLoaderData<typeof loader>();
31
+
32
+ return (
33
+ <div className="collection">
34
+ <h1>Products</h1>
35
+ <Pagination connection={products}>
36
+ {({nodes, isLoading, PreviousLink, NextLink}) => (
37
+ <>
38
+ <PreviousLink>
39
+ {isLoading ? 'Loading...' : <span>↑ Load previous</span>}
40
+ </PreviousLink>
41
+ <ProductsGrid products={nodes} />
42
+ <br />
43
+ <NextLink>
44
+ {isLoading ? 'Loading...' : <span>Load more ↓</span>}
45
+ </NextLink>
46
+ </>
47
+ )}
48
+ </Pagination>
49
+ </div>
50
+ );
51
+ }
52
+
53
+ function ProductsGrid({products}: {products: ProductItemFragment[]}) {
54
+ return (
55
+ <div className="products-grid">
56
+ {products.map((product, index) => {
57
+ return (
58
+ <ProductItem
59
+ key={product.id}
60
+ product={product}
61
+ loading={index < 8 ? 'eager' : undefined}
62
+ />
63
+ );
64
+ })}
65
+ </div>
66
+ );
67
+ }
68
+
69
+ function ProductItem({
70
+ product,
71
+ loading,
72
+ }: {
73
+ product: ProductItemFragment;
74
+ loading?: 'eager' | 'lazy';
75
+ }) {
76
+ const variant = product.variants.nodes[0];
77
+ const variantUrl = useVariantUrl(product.handle, variant.selectedOptions);
78
+ return (
79
+ <Link
80
+ className="product-item"
81
+ key={product.id}
82
+ prefetch="intent"
83
+ to={variantUrl}
84
+ >
85
+ {product.featuredImage && (
86
+ <Image
87
+ alt={product.featuredImage.altText || product.title}
88
+ aspectRatio="1/1"
89
+ data={product.featuredImage}
90
+ loading={loading}
91
+ sizes="(min-width: 45em) 400px, 100vw"
92
+ />
93
+ )}
94
+ <h4>{product.title}</h4>
95
+ <small>
96
+ <Money data={product.priceRange.minVariantPrice} />
97
+ </small>
98
+ </Link>
99
+ );
100
+ }
101
+
102
+ const PRODUCT_ITEM_FRAGMENT = `#graphql
103
+ fragment MoneyProductItem on MoneyV2 {
104
+ amount
105
+ currencyCode
106
+ }
107
+ fragment ProductItem on Product {
108
+ id
109
+ handle
110
+ title
111
+ featuredImage {
112
+ id
113
+ altText
114
+ url
115
+ width
116
+ height
117
+ }
118
+ priceRange {
119
+ minVariantPrice {
120
+ ...MoneyProductItem
121
+ }
122
+ maxVariantPrice {
123
+ ...MoneyProductItem
124
+ }
125
+ }
126
+ variants(first: 1) {
127
+ nodes {
128
+ selectedOptions {
129
+ name
130
+ value
131
+ }
132
+ }
133
+ }
134
+ }
135
+ ` as const;
136
+
137
+ // NOTE: https://shopify.dev/docs/api/storefront/2024-01/objects/product
138
+ const CATALOG_QUERY = `#graphql
139
+ query Catalog(
140
+ $country: CountryCode
141
+ $language: LanguageCode
142
+ $first: Int
143
+ $last: Int
144
+ $startCursor: String
145
+ $endCursor: String
146
+ ) @inContext(country: $country, language: $language) {
147
+ products(first: $first, last: $last, before: $startCursor, after: $endCursor) {
148
+ nodes {
149
+ ...ProductItem
150
+ }
151
+ pageInfo {
152
+ hasPreviousPage
153
+ hasNextPage
154
+ startCursor
155
+ endCursor
156
+ }
157
+ }
158
+ }
159
+ ${PRODUCT_ITEM_FRAGMENT}
160
+ ` as const;
@@ -12,7 +12,6 @@ import type {
12
12
  ProductVariantsQuery,
13
13
  ProductVariantFragment,
14
14
  } from 'storefrontapi.generated';
15
-
16
15
  import {
17
16
  Image,
18
17
  Money,
@@ -27,7 +26,7 @@ import type {
27
26
  } from '@shopify/hydrogen/storefront-api-types';
28
27
  import {getVariantUrl} from '~/lib/variants';
29
28
 
30
- export const meta: MetaFunction<typeof loader> = ({data}) => {
29
+ export const meta: MetaFunction<typeof loader> = ({data, location}) => {
31
30
  return [{title: `Hydrogen | ${data?.product.title ?? ''}`}];
32
31
  };
33
32
 
@@ -68,7 +68,7 @@ export type CustomerAddressCreateMutation = {
68
68
 
69
69
  export type CustomerFragment = Pick<
70
70
  CustomerAccountAPI.Customer,
71
- 'firstName' | 'lastName'
71
+ 'id' | 'firstName' | 'lastName'
72
72
  > & {
73
73
  defaultAddress?: CustomerAccountAPI.Maybe<
74
74
  Pick<
@@ -129,7 +129,10 @@ export type CustomerDetailsQueryVariables = CustomerAccountAPI.Exact<{
129
129
  }>;
130
130
 
131
131
  export type CustomerDetailsQuery = {
132
- customer: Pick<CustomerAccountAPI.Customer, 'firstName' | 'lastName'> & {
132
+ customer: Pick<
133
+ CustomerAccountAPI.Customer,
134
+ 'id' | 'firstName' | 'lastName'
135
+ > & {
133
136
  defaultAddress?: CustomerAccountAPI.Maybe<
134
137
  Pick<
135
138
  CustomerAccountAPI.CustomerAddress,
@@ -467,7 +470,7 @@ export type CustomerUpdateMutation = {
467
470
  };
468
471
 
469
472
  interface GeneratedQueryTypes {
470
- '#graphql\n query CustomerDetails {\n customer {\n ...Customer\n }\n }\n #graphql\n fragment Customer on Customer {\n firstName\n lastName\n defaultAddress {\n ...Address\n }\n addresses(first: 6) {\n nodes {\n ...Address\n }\n }\n }\n fragment Address on CustomerAddress {\n id\n formatted\n firstName\n lastName\n company\n address1\n address2\n territoryCode\n zoneCode\n city\n zip\n phoneNumber\n }\n\n': {
473
+ '#graphql\n query CustomerDetails {\n customer {\n ...Customer\n }\n }\n #graphql\n fragment Customer on Customer {\n id\n firstName\n lastName\n defaultAddress {\n ...Address\n }\n addresses(first: 6) {\n nodes {\n ...Address\n }\n }\n }\n fragment Address on CustomerAddress {\n id\n formatted\n firstName\n lastName\n company\n address1\n address2\n territoryCode\n zoneCode\n city\n zip\n phoneNumber\n }\n\n': {
471
474
  return: CustomerDetailsQuery;
472
475
  variables: CustomerDetailsQueryVariables;
473
476
  };
@@ -1,4 +1,4 @@
1
- /// <reference types="@remix-run/dev" />
1
+ /// <reference types="vite/client" />
2
2
  /// <reference types="@shopify/remix-oxygen" />
3
3
  /// <reference types="@shopify/oxygen-workers-types" />
4
4
 
@@ -9,6 +9,7 @@ import type {
9
9
  Storefront,
10
10
  CustomerAccount,
11
11
  HydrogenCart,
12
+ HydrogenSessionData,
12
13
  } from '@shopify/hydrogen';
13
14
  import type {AppSession} from '~/lib/session';
14
15
 
@@ -36,7 +37,7 @@ declare module '@shopify/remix-oxygen' {
36
37
  /**
37
38
  * Declare local additions to the Remix loader context.
38
39
  */
39
- export interface AppLoadContext {
40
+ interface AppLoadContext {
40
41
  env: Env;
41
42
  cart: HydrogenCart;
42
43
  storefront: Storefront;
@@ -44,4 +45,9 @@ declare module '@shopify/remix-oxygen' {
44
45
  session: AppSession;
45
46
  waitUntil: ExecutionContext['waitUntil'];
46
47
  }
48
+
49
+ /**
50
+ * Declare local additions to the Remix session data.
51
+ */
52
+ interface SessionData extends HydrogenSessionData {}
47
53
  }
@@ -2,10 +2,10 @@
2
2
  "name": "skeleton",
3
3
  "private": true,
4
4
  "sideEffects": false,
5
- "version": "1.0.6",
6
- "type": "commonjs",
5
+ "version": "1.0.8",
6
+ "type": "module",
7
7
  "scripts": {
8
- "build": "shopify hydrogen build",
8
+ "build": "shopify hydrogen build --codegen",
9
9
  "dev": "shopify hydrogen dev --codegen",
10
10
  "preview": "npm run build && shopify hydrogen preview",
11
11
  "lint": "eslint --no-error-on-unmatched-pattern --ext .js,.ts,.jsx,.tsx .",
@@ -16,19 +16,22 @@
16
16
  "dependencies": {
17
17
  "@remix-run/react": "^2.8.0",
18
18
  "@remix-run/server-runtime": "^2.8.0",
19
- "@shopify/cli": "3.56.3",
20
- "@shopify/cli-hydrogen": "^7.1.2",
21
- "@shopify/hydrogen": "~2024.1.4",
22
- "@shopify/remix-oxygen": "^2.0.3",
19
+ "@shopify/cli": "3.58.0",
20
+ "@shopify/cli-hydrogen": "^8.0.1",
21
+ "@shopify/hydrogen": "2024.4.1",
22
+ "@shopify/remix-oxygen": "^2.0.4",
23
23
  "graphql": "^16.6.0",
24
24
  "graphql-tag": "^2.12.6",
25
- "isbot": "^3.6.6",
25
+ "isbot": "^3.8.0",
26
26
  "react": "^18.2.0",
27
27
  "react-dom": "^18.2.0"
28
28
  },
29
29
  "devDependencies": {
30
+ "@graphql-codegen/cli": "5.0.2",
30
31
  "@remix-run/dev": "^2.8.0",
31
32
  "@remix-run/eslint-config": "^2.8.0",
33
+ "@shopify/hydrogen-codegen": "^0.3.0",
34
+ "@shopify/mini-oxygen": "^3.0.1",
32
35
  "@shopify/oxygen-workers-types": "^4.0.0",
33
36
  "@shopify/prettier-config": "^1.1.2",
34
37
  "@total-typescript/ts-reset": "^0.4.2",
@@ -38,7 +41,9 @@
38
41
  "eslint": "^8.20.0",
39
42
  "eslint-plugin-hydrogen": "0.12.2",
40
43
  "prettier": "^2.8.4",
41
- "typescript": "^5.2.2"
44
+ "typescript": "^5.2.2",
45
+ "vite": "^5.1.0",
46
+ "vite-tsconfig-paths": "^4.3.1"
42
47
  },
43
48
  "engines": {
44
49
  "node": ">=18.0.0"