@shopify/cli-hydrogen 9.0.11 → 10.0.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.
@@ -1,5 +1,26 @@
1
1
  # skeleton
2
2
 
3
+ ## 2025.1.6
4
+
5
+ ### Patch Changes
6
+
7
+ - 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)
8
+
9
+ 1. If you have a separate `app/layout.tsx` file, delete it and move its default exported component into your `root.tsx`. For example:
10
+
11
+ ```ts
12
+ // /app/root.tsx
13
+ export function Layout({children}: {children?: React.ReactNode}) {
14
+ const nonce = useNonce();
15
+ const data = useRouteLoaderData<RootLoader>('root');
16
+
17
+ return (
18
+ <html lang="en">
19
+ ...
20
+ );
21
+ }
22
+ ```
23
+
3
24
  ## 2025.1.5
4
25
 
5
26
  ### Patch Changes
@@ -39,7 +60,30 @@
39
60
 
40
61
  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)
41
62
 
42
- 1. Add the following npm package dev dependencies:
63
+ 1. Update your `vite.config.ts`.
64
+
65
+ ```diff
66
+ export default defineConfig({
67
+ plugins: [
68
+ hydrogen(),
69
+ oxygen(),
70
+ remix({
71
+ - presets: [hydrogen.preset()],
72
+ + presets: [hydrogen.v3preset()],
73
+ future: {
74
+ v3_fetcherPersist: true,
75
+ v3_relativeSplatPath: true,
76
+ v3_throwAbortReason: true,
77
+ v3_lazyRouteDiscovery: true,
78
+ v3_singleFetch: true,
79
+ + v3_routeConfig: true,
80
+ },
81
+ }),
82
+ tsconfigPaths(),
83
+ ],
84
+ ```
85
+
86
+ 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:
43
87
 
44
88
  ```diff
45
89
  "devDependencies": {
@@ -48,22 +92,29 @@
48
92
  + "@remix-run/route-config": "^2.16.1",
49
93
  ```
50
94
 
51
- 1. If you have `export function Layout` in your `root.tsx`, move this export into its own file. For example:
95
+ 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.
52
96
 
53
97
  ```ts
54
98
  // /app/layout.tsx
99
+ import {Outlet} from '@remix-run/react';
100
+
55
101
  export default function Layout() {
56
102
  const nonce = useNonce();
57
103
  const data = useRouteLoaderData<RootLoader>('root');
58
104
 
59
105
  return (
60
106
  <html lang="en">
61
- ...
107
+ ...
108
+ <Outlet />
109
+ ...
110
+ </html>
62
111
  );
63
112
  }
113
+
114
+ // Remember to remove the Layout export from your root.tsx
64
115
  ```
65
116
 
66
- 1. Create a `routes.ts` file.
117
+ 1. Add a routes.ts file. This is your new Remix route configuration file.
67
118
 
68
119
  ```ts
69
120
  import { flatRoutes } from "@remix-run/fs-routes";
@@ -76,18 +127,6 @@
76
127
  ]) satisfies RouteConfig;
77
128
  ```
78
129
 
79
- 1. Update your `vite.config.ts`.
80
-
81
- ```diff
82
- export default defineConfig({
83
- plugins: [
84
- hydrogen(),
85
- oxygen(),
86
- remix({
87
- - presets: [hydrogen.preset()],
88
- + presets: [hydrogen.v3preset()],
89
- ```
90
-
91
130
  - Updated dependencies [[`0425e50d`](https://github.com/Shopify/hydrogen/commit/0425e50dafe2f42326cba67076e5fcea2905e885), [`74ef1ba7`](https://github.com/Shopify/hydrogen/commit/74ef1ba7d41988350e9d2c81731c90381943d1f0)]:
92
131
  - @shopify/remix-oxygen@2.0.12
93
132
  - @shopify/hydrogen@2025.1.3
@@ -1,13 +1,21 @@
1
- import {getShopAnalytics} from '@shopify/hydrogen';
1
+ import {Analytics, getShopAnalytics, useNonce} from '@shopify/hydrogen';
2
2
  import {type LoaderFunctionArgs} from '@shopify/remix-oxygen';
3
3
  import {
4
4
  Outlet,
5
5
  useRouteError,
6
6
  isRouteErrorResponse,
7
7
  type ShouldRevalidateFunction,
8
+ Links,
9
+ Meta,
10
+ Scripts,
11
+ ScrollRestoration,
12
+ useRouteLoaderData,
8
13
  } from '@remix-run/react';
9
14
  import favicon from '~/assets/favicon.svg';
10
15
  import {FOOTER_QUERY, HEADER_QUERY} from '~/lib/fragments';
16
+ import resetStyles from '~/styles/reset.css?url';
17
+ import appStyles from '~/styles/app.css?url';
18
+ import {PageLayout} from './components/PageLayout';
11
19
 
12
20
  export type RootLoader = typeof loader;
13
21
 
@@ -25,9 +33,9 @@ export const shouldRevalidate: ShouldRevalidateFunction = ({
25
33
  // revalidate when manually revalidating via useRevalidator
26
34
  if (currentUrl.toString() === nextUrl.toString()) return true;
27
35
 
28
- // Defaulting to no revalidation for root loader data to improve performance.
29
- // When using this feature, you risk your UI getting out of sync with your server.
30
- // Use with caution. If you are uncomfortable with this optimization, update the
36
+ // Defaulting to no revalidation for root loader data to improve performance.
37
+ // When using this feature, you risk your UI getting out of sync with your server.
38
+ // Use with caution. If you are uncomfortable with this optimization, update the
31
39
  // line below to `return defaultShouldRevalidate` instead.
32
40
  // For more details see: https://remix.run/docs/en/main/route/should-revalidate
33
41
  return false;
@@ -133,6 +141,39 @@ function loadDeferredData({context}: LoaderFunctionArgs) {
133
141
  };
134
142
  }
135
143
 
144
+ export function Layout({children}: {children?: React.ReactNode}) {
145
+ const nonce = useNonce();
146
+ const data = useRouteLoaderData<RootLoader>('root');
147
+
148
+ return (
149
+ <html lang="en">
150
+ <head>
151
+ <meta charSet="utf-8" />
152
+ <meta name="viewport" content="width=device-width,initial-scale=1" />
153
+ <link rel="stylesheet" href={resetStyles}></link>
154
+ <link rel="stylesheet" href={appStyles}></link>
155
+ <Meta />
156
+ <Links />
157
+ </head>
158
+ <body>
159
+ {data ? (
160
+ <Analytics.Provider
161
+ cart={data.cart}
162
+ shop={data.shop}
163
+ consent={data.consent}
164
+ >
165
+ <PageLayout {...data}>{children}</PageLayout>
166
+ </Analytics.Provider>
167
+ ) : (
168
+ children
169
+ )}
170
+ <ScrollRestoration nonce={nonce} />
171
+ <Scripts nonce={nonce} />
172
+ </body>
173
+ </html>
174
+ );
175
+ }
176
+
136
177
  export default function App() {
137
178
  return <Outlet />;
138
179
  }
@@ -1,7 +1,9 @@
1
1
  import {flatRoutes} from '@remix-run/fs-routes';
2
- import {layout, type RouteConfig} from '@remix-run/route-config';
2
+ import {type RouteConfig} from '@remix-run/route-config';
3
3
  import {hydrogenRoutes} from '@shopify/hydrogen';
4
4
 
5
5
  export default hydrogenRoutes([
6
- layout('./layout.tsx', (await flatRoutes())),
6
+ ...(await flatRoutes()),
7
+ // Manual route definitions can be added to this array, in addition to or instead of using the `flatRoutes` file-based routing convention.
8
+ // See https://remix.run/docs/en/main/guides/routing for more details
7
9
  ]) satisfies RouteConfig;
@@ -2,7 +2,7 @@
2
2
  "name": "skeleton",
3
3
  "private": true,
4
4
  "sideEffects": false,
5
- "version": "2025.1.5",
5
+ "version": "2025.1.6",
6
6
  "type": "module",
7
7
  "scripts": {
8
8
  "build": "shopify hydrogen build --codegen",
@@ -34,7 +34,7 @@
34
34
  "@remix-run/route-config": "^2.16.1",
35
35
  "@shopify/cli": "~3.77.1",
36
36
  "@shopify/hydrogen-codegen": "^0.3.3",
37
- "@shopify/mini-oxygen": "^3.1.2",
37
+ "@shopify/mini-oxygen": "^3.2.0",
38
38
  "@shopify/oxygen-workers-types": "^4.1.6",
39
39
  "@shopify/prettier-config": "^1.1.2",
40
40
  "@total-typescript/ts-reset": "^0.6.1",
@@ -13,6 +13,7 @@ import { getCliCommand } from '../../lib/shell.js';
13
13
  import { commonFlags, flagsToCamelObject } from '../../lib/flags.js';
14
14
  import { getProjectPaths } from '../../lib/remix-config.js';
15
15
  import { isHydrogenMonorepo, hydrogenPackagesPath } from '../../lib/build.js';
16
+ import { fetch } from '@shopify/cli-kit/node/http';
16
17
 
17
18
  const INSTRUCTIONS_FOLDER = ".hydrogen";
18
19
  class Upgrade extends Command {
@@ -73,14 +73,9 @@ async function handleRouteGeneration(controller, flagRoutes) {
73
73
  }
74
74
  function generateProjectEntries(options) {
75
75
  return Promise.all(
76
- [
77
- "routes.ts",
78
- "layout.tsx",
79
- "root",
80
- "entry.server",
81
- "entry.client",
82
- "../server.ts"
83
- ].map((filename) => generateProjectFile(filename, options))
76
+ ["routes.ts", "root", "entry.server", "entry.client", "../server.ts"].map(
77
+ (filename) => generateProjectFile(filename, options)
78
+ )
84
79
  );
85
80
  }
86
81
  async function handleCliShortcut(controller, cliCommand, flagShortcut) {
@@ -3,10 +3,7 @@ import { findFileWithExtension, replaceFileContent } from '../../file.js';
3
3
  import { importLangAstGrep } from '../../ast.js';
4
4
 
5
5
  async function replaceRootLinks(appDirectory, formatConfig, importer) {
6
- const { filepath, astType } = await findFileWithExtension(
7
- appDirectory,
8
- "layout"
9
- );
6
+ const { filepath, astType } = await findFileWithExtension(appDirectory, "root");
10
7
  if (!filepath || !astType) {
11
8
  throw new AbortError(`Could not find root file in ${appDirectory}`);
12
9
  }
@@ -1748,5 +1748,5 @@
1748
1748
  ]
1749
1749
  }
1750
1750
  },
1751
- "version": "9.0.11"
1751
+ "version": "10.0.0"
1752
1752
  }
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "access": "public",
5
5
  "@shopify:registry": "https://registry.npmjs.org"
6
6
  },
7
- "version": "9.0.11",
7
+ "version": "10.0.0",
8
8
  "license": "MIT",
9
9
  "type": "module",
10
10
  "repository": {
@@ -62,7 +62,7 @@
62
62
  "@graphql-codegen/cli": "^5.0.2",
63
63
  "@remix-run/dev": "^2.16.1",
64
64
  "@shopify/hydrogen-codegen": "^0.3.3",
65
- "@shopify/mini-oxygen": "^3.1.2",
65
+ "@shopify/mini-oxygen": "^3.2.0",
66
66
  "graphql-config": "^5.0.3",
67
67
  "vite": "^5.1.0 || ^6.2.0"
68
68
  },
@@ -1,46 +0,0 @@
1
- import {useNonce, Analytics} from '@shopify/hydrogen';
2
- import {
3
- Links,
4
- Meta,
5
- Scripts,
6
- useRouteLoaderData,
7
- ScrollRestoration,
8
- Outlet,
9
- } from '@remix-run/react';
10
- import resetStyles from '~/styles/reset.css?url';
11
- import appStyles from '~/styles/app.css?url';
12
- import {PageLayout} from '~/components/PageLayout';
13
- import { RootLoader } from './root';
14
-
15
- export default function Layout() {
16
- const nonce = useNonce();
17
- const data = useRouteLoaderData<RootLoader>('root');
18
-
19
- return (
20
- <html lang="en">
21
- <head>
22
- <meta charSet="utf-8" />
23
- <meta name="viewport" content="width=device-width,initial-scale=1" />
24
- <link rel="stylesheet" href={resetStyles}></link>
25
- <link rel="stylesheet" href={appStyles}></link>
26
- <Meta />
27
- <Links />
28
- </head>
29
- <body>
30
- {data ? (
31
- <Analytics.Provider
32
- cart={data.cart}
33
- shop={data.shop}
34
- consent={data.consent}
35
- >
36
- <PageLayout {...data}><Outlet /></PageLayout>
37
- </Analytics.Provider>
38
- ) : (
39
- <Outlet />
40
- )}
41
- <ScrollRestoration nonce={nonce} />
42
- <Scripts nonce={nonce} />
43
- </body>
44
- </html>
45
- );
46
- }