@shopify/cli 3.61.0 → 3.61.2
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.
- package/dist/assets/hydrogen/starter/.eslintrc.cjs +1 -0
- package/dist/assets/hydrogen/starter/CHANGELOG.md +65 -65
- package/dist/assets/hydrogen/starter/app/components/Footer.tsx +3 -3
- package/dist/assets/hydrogen/starter/app/components/PageLayout.tsx +1 -1
- package/dist/assets/hydrogen/starter/app/lib/session.ts +5 -0
- package/dist/assets/hydrogen/starter/app/root.tsx +84 -51
- package/dist/assets/hydrogen/starter/app/routes/_index.tsx +62 -25
- package/dist/assets/hydrogen/starter/app/routes/account.$.tsx +1 -5
- package/dist/assets/hydrogen/starter/app/routes/account.addresses.tsx +12 -70
- package/dist/assets/hydrogen/starter/app/routes/account.orders.$id.tsx +7 -14
- package/dist/assets/hydrogen/starter/app/routes/account.orders._index.tsx +1 -8
- package/dist/assets/hydrogen/starter/app/routes/account.profile.tsx +5 -22
- package/dist/assets/hydrogen/starter/app/routes/account.tsx +0 -1
- package/dist/assets/hydrogen/starter/app/routes/blogs.$blogHandle.$articleHandle.tsx +32 -6
- package/dist/assets/hydrogen/starter/app/routes/blogs.$blogHandle._index.tsx +36 -10
- package/dist/assets/hydrogen/starter/app/routes/blogs._index.tsx +35 -12
- package/dist/assets/hydrogen/starter/app/routes/cart.tsx +0 -2
- package/dist/assets/hydrogen/starter/app/routes/collections.$handle.tsx +40 -7
- package/dist/assets/hydrogen/starter/app/routes/collections._index.tsx +32 -6
- package/dist/assets/hydrogen/starter/app/routes/collections.all.tsx +31 -6
- package/dist/assets/hydrogen/starter/app/routes/pages.$handle.tsx +36 -8
- package/dist/assets/hydrogen/starter/app/routes/products.$handle.tsx +50 -11
- package/dist/assets/hydrogen/starter/package.json +6 -7
- package/dist/assets/hydrogen/starter/server.ts +4 -0
- package/dist/assets/hydrogen/virtual-routes/components/RequestDetails.jsx +1 -2
- package/dist/assets/hydrogen/virtual-routes/components/RequestTable.jsx +1 -2
- package/dist/assets/hydrogen/virtual-routes/routes/index.jsx +1 -2
- package/dist/{chunk-ZOTASNQ2.js → chunk-3RM5SOXY.js} +1 -1
- package/dist/{chunk-Q7PY7LVL.js → chunk-4757GPBG.js} +3 -3
- package/dist/{chunk-FFHJRSIP.js → chunk-4L37JOS5.js} +1 -1
- package/dist/{chunk-V67RXPI6.js → chunk-4TTAP7NN.js} +3 -3
- package/dist/{chunk-IIVL4DYB.js → chunk-5B2D56W6.js} +2 -2
- package/dist/{chunk-QX3YP6O5.js → chunk-5KRK4DLX.js} +2598 -795
- package/dist/{chunk-FWKRA64T.js → chunk-5MODHNUE.js} +3 -3
- package/dist/{chunk-LXXUWZRO.js → chunk-7IZTLXJ5.js} +2 -2
- package/dist/{chunk-AL4KPZUN.js → chunk-BUWM6JUU.js} +2 -2
- package/dist/{chunk-WNXHHHLZ.js → chunk-BYFLATOA.js} +3 -3
- package/dist/{chunk-4IXC46ZA.js → chunk-CK7MF3LY.js} +4 -4
- package/dist/{chunk-2AH5EBXL.js → chunk-CTETXMMM.js} +4 -4
- package/dist/{chunk-7YJH7P7B.js → chunk-CWYZA7C7.js} +1 -1
- package/dist/{chunk-463OPQAS.js → chunk-EHF6FVWH.js} +1 -1
- package/dist/{chunk-CMFKWJDJ.js → chunk-ETSILRIY.js} +3 -3
- package/dist/{chunk-EDVQGTOL.js → chunk-G4EQLT5B.js} +4 -4
- package/dist/{chunk-DWXXFI3U.js → chunk-JQPQJN44.js} +6 -6
- package/dist/{chunk-YZIPQNOG.js → chunk-KBXWK6XB.js} +2 -2
- package/dist/{chunk-EFL5CN6M.js → chunk-M73YMW2C.js} +4 -4
- package/dist/{chunk-HJ2JCW7E.js → chunk-NBIE3DNN.js} +2 -2
- package/dist/{chunk-2RKUO75O.js → chunk-NJP5GFNN.js} +129 -125
- package/dist/{chunk-TXDYKQZT.js → chunk-NJTSDTDU.js} +4 -4
- package/dist/{chunk-UJQBYPRO.js → chunk-OC4AY5G7.js} +1 -1
- package/dist/{chunk-75BJ33EP.js → chunk-Q3KADKQA.js} +2 -2
- package/dist/{chunk-LY6UIYOG.js → chunk-QDZF6IG4.js} +2 -2
- package/dist/{chunk-XDCNK2SU.js → chunk-QLLSCNEC.js} +2 -2
- package/dist/{chunk-O53XNGJU.js → chunk-QQP6JS5H.js} +1 -1
- package/dist/{chunk-2Q7SKRRM.js → chunk-QSO3GQEK.js} +162 -132
- package/dist/{chunk-5NBS5LAW.js → chunk-QTBH3GO6.js} +1 -1
- package/dist/{chunk-JZ5DN7RX.js → chunk-RPRKZ6JC.js} +2509 -728
- package/dist/{chunk-ONJCU4C5.js → chunk-TXXQWILO.js} +2 -2
- package/dist/{chunk-B4KDQK3X.js → chunk-UPM6XNBH.js} +2 -2
- package/dist/{chunk-3W2QB2OC.js → chunk-VC6CC75R.js} +2 -2
- package/dist/{chunk-XRFOYWYI.js → chunk-WZBNLCJ5.js} +2 -2
- package/dist/{chunk-63QEL3SZ.js → chunk-XMJDBJPP.js} +4 -4
- package/dist/{chunk-OOAZSPYS.js → chunk-YP5UVIUW.js} +3 -3
- package/dist/{chunk-LUGC3D2G.js → chunk-YWPV7MV2.js} +6 -6
- package/dist/{chunk-ABZKHSZ5.js → chunk-YZGLFVKK.js} +1 -1
- package/dist/{chunk-RW6YXHBL.js → chunk-ZE2ZPLYI.js} +12 -12
- package/dist/cli/commands/auth/logout.js +18 -18
- package/dist/cli/commands/auth/logout.test.js +19 -19
- package/dist/cli/commands/debug/command-flags.js +17 -17
- package/dist/cli/commands/demo/catalog.js +18 -18
- package/dist/cli/commands/demo/generate-file.js +18 -18
- package/dist/cli/commands/demo/index.js +17 -17
- package/dist/cli/commands/demo/print-ai-prompt.js +18 -18
- package/dist/cli/commands/docs/generate.js +17 -17
- package/dist/cli/commands/docs/generate.test.js +17 -17
- package/dist/cli/commands/help.js +17 -17
- package/dist/cli/commands/kitchen-sink/async.js +18 -18
- package/dist/cli/commands/kitchen-sink/async.test.js +18 -18
- package/dist/cli/commands/kitchen-sink/index.js +20 -20
- package/dist/cli/commands/kitchen-sink/index.test.js +20 -20
- package/dist/cli/commands/kitchen-sink/prompts.js +18 -18
- package/dist/cli/commands/kitchen-sink/prompts.test.js +18 -18
- package/dist/cli/commands/kitchen-sink/static.js +18 -18
- package/dist/cli/commands/kitchen-sink/static.test.js +18 -18
- package/dist/cli/commands/search.js +18 -18
- package/dist/cli/commands/upgrade.js +17 -17
- package/dist/cli/commands/version.js +18 -18
- package/dist/cli/commands/version.test.js +18 -18
- package/dist/cli/services/commands/search.js +8 -8
- package/dist/cli/services/commands/search.test.js +8 -8
- package/dist/cli/services/commands/version.js +11 -11
- package/dist/cli/services/commands/version.test.js +12 -12
- package/dist/cli/services/demo.js +8 -8
- package/dist/cli/services/demo.test.js +8 -8
- package/dist/cli/services/kitchen-sink/async.js +8 -8
- package/dist/cli/services/kitchen-sink/prompts.js +8 -8
- package/dist/cli/services/kitchen-sink/static.js +8 -8
- package/dist/cli/services/upgrade.js +10 -10
- package/dist/cli/services/upgrade.test.js +11 -11
- package/dist/{custom-oclif-loader-KLTAWG4B-VOMMA3PO.js → custom-oclif-loader-4SQGUQ7D-P5C4NLSX.js} +4 -4
- package/dist/{chunk-5R5656YY.js → custom-oclif-loader-OD47SFAU.js} +18 -3
- package/dist/{error-handler-UJK7WNJE.js → error-handler-EPMFPTYX.js} +10 -10
- package/dist/{error-handler-ND7WBMC3-CRFJKAS4.js → error-handler-WI4YVJIS-U3BMMYNJ.js} +6 -6
- package/dist/{error-handler-FUQWOW4J.js → error-handler-WL3Q25NI.js} +15 -15
- package/dist/hooks/postrun.js +13 -13
- package/dist/hooks/prerun.js +10 -10
- package/dist/index.js +1137 -1104
- package/dist/{lib-76RCE6WZ-AR3SQY6Y.js → lib-76RCE6WZ-5IYGTKKK.js} +2 -2
- package/dist/{lib-MWSNLG5P.js → lib-UYK3ZLZK.js} +3 -3
- package/dist/{local-5OND5PI5.js → local-KISH2IRF.js} +7 -7
- package/dist/{local-3LWDOA7J-UFWE2V6L.js → local-YKOG4EUR-XRRBWLSI.js} +4 -4
- package/dist/{morph-FQNWYET7.js → morph-DCIZUK2Q.js} +25 -8
- package/dist/{node-WNJUHXTR.js → node-3DKQAOFU.js} +14 -14
- package/dist/{node-package-manager-ISP2P5R3.js → node-package-manager-HYTHPJBI.js} +9 -9
- package/dist/{node-package-manager-TFY2ROCP-DDJAU44T.js → node-package-manager-S7TSAUJZ-KKDY6KSF.js} +5 -5
- package/dist/{system-G445DF53.js → system-LIP7AECY.js} +7 -7
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/{ui-ITQVVPJU.js → ui-5LSDG3C5.js} +7 -7
- package/dist/{ui-MUGCNPLG-UG4N3GMV.js → ui-FUZYK6S3-PVVDPVD5.js} +4 -4
- package/dist/{workerd-EZVOCUQW.js → workerd-TFH7T6NI.js} +13 -13
- package/oclif.manifest.json +1 -1
- package/package.json +4 -5
- package/dist/custom-oclif-loader-PJJ3H2WB.js +0 -28
- package/dist/hooks/init.d.ts +0 -12
- package/dist/hooks/init.js +0 -66
- package/dist/hooks/init.js.map +0 -1
- package/dist/{chunk-67MDUPX5.js → chunk-I434ZJQI.js} +7 -7
- package/dist/{chunk-74JT4RJX.js → chunk-VF4VWJWS.js} +3 -3
|
@@ -1,91 +1,91 @@
|
|
|
1
1
|
# skeleton
|
|
2
2
|
|
|
3
|
-
## 0.0.0-next-
|
|
3
|
+
## 0.0.0-next-9eb60d7-20240607102913
|
|
4
4
|
|
|
5
5
|
### Patch Changes
|
|
6
6
|
|
|
7
|
-
-
|
|
7
|
+
- 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)
|
|
8
|
+
|
|
9
|
+
Step 1: Add `isPending` implementation in session
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
```diff
|
|
12
|
+
// in app/lib/session.ts
|
|
13
|
+
export class AppSession implements HydrogenSession {
|
|
14
|
+
+ public isPending = false;
|
|
10
15
|
|
|
11
|
-
|
|
16
|
+
get unset() {
|
|
17
|
+
+ this.isPending = true;
|
|
18
|
+
return this.#session.unset;
|
|
19
|
+
}
|
|
12
20
|
|
|
13
|
-
|
|
21
|
+
get set() {
|
|
22
|
+
+ this.isPending = true;
|
|
23
|
+
return this.#session.set;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
commit() {
|
|
27
|
+
+ this.isPending = false;
|
|
28
|
+
return this.#sessionStorage.commitSession(this.#session);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
```
|
|
14
32
|
|
|
15
|
-
|
|
33
|
+
Step 2: update response header if `session.isPending` is true
|
|
16
34
|
|
|
17
35
|
```diff
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
+
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
36
|
+
// in server.ts
|
|
37
|
+
export default {
|
|
38
|
+
async fetch(request: Request): Promise<Response> {
|
|
39
|
+
try {
|
|
40
|
+
const response = await handleRequest(request);
|
|
41
|
+
|
|
42
|
+
+ if (session.isPending) {
|
|
43
|
+
+ response.headers.set('Set-Cookie', await session.commit());
|
|
44
|
+
+ }
|
|
45
|
+
|
|
46
|
+
return response;
|
|
47
|
+
} catch (error) {
|
|
48
|
+
...
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
```
|
|
31
53
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
+ ) : (
|
|
44
|
-
+ children
|
|
45
|
-
+ )}
|
|
46
|
-
</body>
|
|
47
|
-
</html>
|
|
54
|
+
Step 3: remove setting cookie with session.commit() in routes
|
|
55
|
+
|
|
56
|
+
```diff
|
|
57
|
+
// in route files
|
|
58
|
+
export async function loader({context}: LoaderFunctionArgs) {
|
|
59
|
+
return json({},
|
|
60
|
+
- {
|
|
61
|
+
- headers: {
|
|
62
|
+
- 'Set-Cookie': await context.session.commit(),
|
|
63
|
+
- },
|
|
64
|
+
},
|
|
48
65
|
);
|
|
49
66
|
}
|
|
67
|
+
```
|
|
50
68
|
|
|
51
|
-
|
|
52
|
-
+ return <Outlet />;
|
|
53
|
-
+}
|
|
69
|
+
- Trigger changeset for all packages for next release
|
|
54
70
|
|
|
55
|
-
|
|
56
|
-
|
|
71
|
+
- Updated dependencies [[`4337200c`](https://github.com/Shopify/hydrogen/commit/4337200c7908d56c039171c283a4d92c31a8b7b6), [`10a419bf`](https://github.com/Shopify/hydrogen/commit/10a419bf1db79cdfd8c41c0223ce695959f60da9), [`4337200c`](https://github.com/Shopify/hydrogen/commit/4337200c7908d56c039171c283a4d92c31a8b7b6), [`9eb60d73`](https://github.com/Shopify/hydrogen/commit/9eb60d73e552c3d22b9325ecbcd5878810893ad3)]:
|
|
72
|
+
- @shopify/hydrogen@0.0.0-next-9eb60d7-20240607102913
|
|
73
|
+
- @shopify/cli-hydrogen@0.0.0-next-9eb60d7-20240607102913
|
|
74
|
+
- @shopify/remix-oxygen@0.0.0-next-9eb60d7-20240607102913
|
|
57
75
|
|
|
58
|
-
|
|
59
|
-
- <html>
|
|
60
|
-
- ...
|
|
61
|
-
- <body>
|
|
62
|
-
- <Layout {...rootData}>
|
|
63
|
-
- <div className="route-error">
|
|
64
|
-
- <h1>Error</h1>
|
|
65
|
-
- ...
|
|
66
|
-
- </div>
|
|
67
|
-
- </Layout>
|
|
68
|
-
- </body>
|
|
69
|
-
- </html>
|
|
70
|
-
+ <div className="route-error">
|
|
71
|
-
+ <h1>Error</h1>
|
|
72
|
-
+ ...
|
|
73
|
-
+ </div>
|
|
74
|
-
);
|
|
75
|
-
}
|
|
76
|
+
## 2024.4.5
|
|
76
77
|
|
|
77
|
-
|
|
78
|
+
### Patch Changes
|
|
78
79
|
|
|
79
|
-
-
|
|
80
|
+
- Update remix to v2.9.2 ([#2135](https://github.com/Shopify/hydrogen/pull/2135)) by [@michenly](https://github.com/michenly)
|
|
80
81
|
|
|
81
|
-
-
|
|
82
|
+
- `<Analytics>` and `useAnalytics` are now stable. ([#2141](https://github.com/Shopify/hydrogen/pull/2141)) by [@wizardlyhel](https://github.com/wizardlyhel)
|
|
82
83
|
|
|
83
84
|
- 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)
|
|
84
85
|
|
|
85
|
-
- 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), [`
|
|
86
|
-
- @shopify/hydrogen@
|
|
87
|
-
- @shopify/cli-hydrogen@
|
|
88
|
-
- @shopify/remix-oxygen@0.0.0-next-ca7f288-20240530103543
|
|
86
|
+
- 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)]:
|
|
87
|
+
- @shopify/hydrogen@2024.4.3
|
|
88
|
+
- @shopify/cli-hydrogen@8.1.0
|
|
89
89
|
|
|
90
90
|
## 2024.4.4
|
|
91
91
|
|
|
@@ -3,7 +3,7 @@ import {Await, NavLink} from '@remix-run/react';
|
|
|
3
3
|
import type {FooterQuery, HeaderQuery} from 'storefrontapi.generated';
|
|
4
4
|
|
|
5
5
|
interface FooterProps {
|
|
6
|
-
footer: Promise<FooterQuery>;
|
|
6
|
+
footer: Promise<FooterQuery | null>;
|
|
7
7
|
header: HeaderQuery;
|
|
8
8
|
publicStoreDomain: string;
|
|
9
9
|
}
|
|
@@ -18,7 +18,7 @@ export function Footer({
|
|
|
18
18
|
<Await resolve={footerPromise}>
|
|
19
19
|
{(footer) => (
|
|
20
20
|
<footer className="footer">
|
|
21
|
-
{footer
|
|
21
|
+
{footer?.menu && header.shop.primaryDomain?.url && (
|
|
22
22
|
<FooterMenu
|
|
23
23
|
menu={footer.menu}
|
|
24
24
|
primaryDomainUrl={header.shop.primaryDomain.url}
|
|
@@ -37,7 +37,7 @@ function FooterMenu({
|
|
|
37
37
|
primaryDomainUrl,
|
|
38
38
|
publicStoreDomain,
|
|
39
39
|
}: {
|
|
40
|
-
menu:
|
|
40
|
+
menu: FooterQuery['menu'];
|
|
41
41
|
primaryDomainUrl: FooterProps['header']['shop']['primaryDomain']['url'];
|
|
42
42
|
publicStoreDomain: string;
|
|
43
43
|
}) {
|
|
@@ -11,6 +11,8 @@ import {
|
|
|
11
11
|
* swap out the cookie-based implementation with something else!
|
|
12
12
|
*/
|
|
13
13
|
export class AppSession implements HydrogenSession {
|
|
14
|
+
public isPending = false;
|
|
15
|
+
|
|
14
16
|
#sessionStorage;
|
|
15
17
|
#session;
|
|
16
18
|
|
|
@@ -50,10 +52,12 @@ export class AppSession implements HydrogenSession {
|
|
|
50
52
|
}
|
|
51
53
|
|
|
52
54
|
get unset() {
|
|
55
|
+
this.isPending = true;
|
|
53
56
|
return this.#session.unset;
|
|
54
57
|
}
|
|
55
58
|
|
|
56
59
|
get set() {
|
|
60
|
+
this.isPending = true;
|
|
57
61
|
return this.#session.set;
|
|
58
62
|
}
|
|
59
63
|
|
|
@@ -62,6 +66,7 @@ export class AppSession implements HydrogenSession {
|
|
|
62
66
|
}
|
|
63
67
|
|
|
64
68
|
commit() {
|
|
69
|
+
this.isPending = false;
|
|
65
70
|
return this.#sessionStorage.commitSession(this.#session);
|
|
66
71
|
}
|
|
67
72
|
}
|
|
@@ -56,54 +56,81 @@ export function links() {
|
|
|
56
56
|
];
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
export async function loader(
|
|
60
|
-
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
59
|
+
export async function loader(args: LoaderFunctionArgs) {
|
|
60
|
+
// Start fetching non-critical data without blocking time to first byte
|
|
61
|
+
const deferredData = loadDeferredData(args);
|
|
62
|
+
|
|
63
|
+
// Await the critical data required to render initial state of the page
|
|
64
|
+
const criticalData = await loadCriticalData(args);
|
|
65
|
+
|
|
66
|
+
const {storefront, env} = args.context;
|
|
67
|
+
|
|
68
|
+
return defer({
|
|
69
|
+
...deferredData,
|
|
70
|
+
...criticalData,
|
|
71
|
+
publicStoreDomain: env.PUBLIC_STORE_DOMAIN,
|
|
72
|
+
shop: getShopAnalytics({
|
|
73
|
+
storefront,
|
|
74
|
+
publicStorefrontId: env.PUBLIC_STOREFRONT_ID,
|
|
75
|
+
}),
|
|
76
|
+
consent: {
|
|
77
|
+
checkoutDomain: env.PUBLIC_CHECKOUT_DOMAIN,
|
|
78
|
+
storefrontAccessToken: env.PUBLIC_STOREFRONT_API_TOKEN,
|
|
79
79
|
},
|
|
80
80
|
});
|
|
81
|
+
}
|
|
81
82
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
checkoutDomain: env.PUBLIC_CHECKOUT_DOMAIN,
|
|
95
|
-
storefrontAccessToken: env.PUBLIC_STOREFRONT_API_TOKEN,
|
|
83
|
+
/**
|
|
84
|
+
* Load data necessary for rendering content above the fold. This is the critical data
|
|
85
|
+
* needed to render the page. If it's unavailable, the whole page should 400 or 500 error.
|
|
86
|
+
*/
|
|
87
|
+
async function loadCriticalData({context}: LoaderFunctionArgs) {
|
|
88
|
+
const {storefront} = context;
|
|
89
|
+
|
|
90
|
+
const [header] = await Promise.all([
|
|
91
|
+
storefront.query(HEADER_QUERY, {
|
|
92
|
+
cache: storefront.CacheLong(),
|
|
93
|
+
variables: {
|
|
94
|
+
headerMenuHandle: 'main-menu', // Adjust to your header menu handle
|
|
96
95
|
},
|
|
97
|
-
},
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
96
|
+
}),
|
|
97
|
+
// Add other queries here, so that they are loaded in parallel
|
|
98
|
+
]);
|
|
99
|
+
|
|
100
|
+
return {
|
|
101
|
+
header,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Load data for rendering content below the fold. This data is deferred and will be
|
|
107
|
+
* fetched after the initial page load. If it's unavailable, the page should still 200.
|
|
108
|
+
* Make sure to not throw any errors here, as it will cause the page to 500.
|
|
109
|
+
*/
|
|
110
|
+
function loadDeferredData({context}: LoaderFunctionArgs) {
|
|
111
|
+
const {storefront, customerAccount, cart} = context;
|
|
112
|
+
|
|
113
|
+
// defer the footer query (below the fold)
|
|
114
|
+
const footer = storefront
|
|
115
|
+
.query(FOOTER_QUERY, {
|
|
116
|
+
cache: storefront.CacheLong(),
|
|
117
|
+
variables: {
|
|
118
|
+
footerMenuHandle: 'footer', // Adjust to your footer menu handle
|
|
101
119
|
},
|
|
102
|
-
}
|
|
103
|
-
|
|
120
|
+
})
|
|
121
|
+
.catch((error) => {
|
|
122
|
+
// Log query errors, but don't throw them so the page can still render
|
|
123
|
+
console.error(error);
|
|
124
|
+
return null;
|
|
125
|
+
});
|
|
126
|
+
return {
|
|
127
|
+
cart: cart.get(),
|
|
128
|
+
isLoggedIn: customerAccount.isLoggedIn(),
|
|
129
|
+
footer,
|
|
130
|
+
};
|
|
104
131
|
}
|
|
105
132
|
|
|
106
|
-
|
|
133
|
+
function Layout({children}: {children?: React.ReactNode}) {
|
|
107
134
|
const nonce = useNonce();
|
|
108
135
|
const data = useRouteLoaderData<RootLoader>('root');
|
|
109
136
|
|
|
@@ -135,7 +162,11 @@ export function Layout({children}: {children?: React.ReactNode}) {
|
|
|
135
162
|
}
|
|
136
163
|
|
|
137
164
|
export default function App() {
|
|
138
|
-
return
|
|
165
|
+
return (
|
|
166
|
+
<Layout>
|
|
167
|
+
<Outlet />
|
|
168
|
+
</Layout>
|
|
169
|
+
);
|
|
139
170
|
}
|
|
140
171
|
|
|
141
172
|
export function ErrorBoundary() {
|
|
@@ -151,14 +182,16 @@ export function ErrorBoundary() {
|
|
|
151
182
|
}
|
|
152
183
|
|
|
153
184
|
return (
|
|
154
|
-
<
|
|
155
|
-
<
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
<
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
185
|
+
<Layout>
|
|
186
|
+
<div className="route-error">
|
|
187
|
+
<h1>Oops</h1>
|
|
188
|
+
<h2>{errorStatus}</h2>
|
|
189
|
+
{errorMessage && (
|
|
190
|
+
<fieldset>
|
|
191
|
+
<pre>{errorMessage}</pre>
|
|
192
|
+
</fieldset>
|
|
193
|
+
)}
|
|
194
|
+
</div>
|
|
195
|
+
</Layout>
|
|
163
196
|
);
|
|
164
197
|
}
|
|
@@ -11,13 +11,48 @@ export const meta: MetaFunction = () => {
|
|
|
11
11
|
return [{title: 'Hydrogen | Home'}];
|
|
12
12
|
};
|
|
13
13
|
|
|
14
|
-
export async function loader(
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
const featuredCollection = collections.nodes[0];
|
|
18
|
-
const recommendedProducts = storefront.query(RECOMMENDED_PRODUCTS_QUERY);
|
|
14
|
+
export async function loader(args: LoaderFunctionArgs) {
|
|
15
|
+
// Start fetching non-critical data without blocking time to first byte
|
|
16
|
+
const deferredData = loadDeferredData(args);
|
|
19
17
|
|
|
20
|
-
|
|
18
|
+
// Await the critical data required to render initial state of the page
|
|
19
|
+
const criticalData = await loadCriticalData(args);
|
|
20
|
+
|
|
21
|
+
return defer({...deferredData, ...criticalData});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Load data necessary for rendering content above the fold. This is the critical data
|
|
26
|
+
* needed to render the page. If it's unavailable, the whole page should 400 or 500 error.
|
|
27
|
+
*/
|
|
28
|
+
async function loadCriticalData({context}: LoaderFunctionArgs) {
|
|
29
|
+
const [{collections}] = await Promise.all([
|
|
30
|
+
context.storefront.query(FEATURED_COLLECTION_QUERY),
|
|
31
|
+
// Add other queries here, so that they are loaded in parallel
|
|
32
|
+
]);
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
featuredCollection: collections.nodes[0],
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Load data for rendering content below the fold. This data is deferred and will be
|
|
41
|
+
* fetched after the initial page load. If it's unavailable, the page should still 200.
|
|
42
|
+
* Make sure to not throw any errors here, as it will cause the page to 500.
|
|
43
|
+
*/
|
|
44
|
+
function loadDeferredData({context}: LoaderFunctionArgs) {
|
|
45
|
+
const recommendedProducts = context.storefront
|
|
46
|
+
.query(RECOMMENDED_PRODUCTS_QUERY)
|
|
47
|
+
.catch((error) => {
|
|
48
|
+
// Log query errors, but don't throw them so the page can still render
|
|
49
|
+
console.error(error);
|
|
50
|
+
return null;
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
return {
|
|
54
|
+
recommendedProducts,
|
|
55
|
+
};
|
|
21
56
|
}
|
|
22
57
|
|
|
23
58
|
export default function Homepage() {
|
|
@@ -55,32 +90,34 @@ function FeaturedCollection({
|
|
|
55
90
|
function RecommendedProducts({
|
|
56
91
|
products,
|
|
57
92
|
}: {
|
|
58
|
-
products: Promise<RecommendedProductsQuery>;
|
|
93
|
+
products: Promise<RecommendedProductsQuery | null>;
|
|
59
94
|
}) {
|
|
60
95
|
return (
|
|
61
96
|
<div className="recommended-products">
|
|
62
97
|
<h2>Recommended Products</h2>
|
|
63
98
|
<Suspense fallback={<div>Loading...</div>}>
|
|
64
99
|
<Await resolve={products}>
|
|
65
|
-
{(
|
|
100
|
+
{(response) => (
|
|
66
101
|
<div className="recommended-products-grid">
|
|
67
|
-
{
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
102
|
+
{response
|
|
103
|
+
? response.products.nodes.map((product) => (
|
|
104
|
+
<Link
|
|
105
|
+
key={product.id}
|
|
106
|
+
className="recommended-product"
|
|
107
|
+
to={`/products/${product.handle}`}
|
|
108
|
+
>
|
|
109
|
+
<Image
|
|
110
|
+
data={product.images.nodes[0]}
|
|
111
|
+
aspectRatio="1/1"
|
|
112
|
+
sizes="(min-width: 45em) 20vw, 50vw"
|
|
113
|
+
/>
|
|
114
|
+
<h4>{product.title}</h4>
|
|
115
|
+
<small>
|
|
116
|
+
<Money data={product.priceRange.minVariantPrice} />
|
|
117
|
+
</small>
|
|
118
|
+
</Link>
|
|
119
|
+
))
|
|
120
|
+
: null}
|
|
84
121
|
</div>
|
|
85
122
|
)}
|
|
86
123
|
</Await>
|
|
@@ -4,9 +4,5 @@ import {redirect, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
|
|
|
4
4
|
export async function loader({context}: LoaderFunctionArgs) {
|
|
5
5
|
await context.customerAccount.handleAuthStatus();
|
|
6
6
|
|
|
7
|
-
return redirect('/account'
|
|
8
|
-
headers: {
|
|
9
|
-
'Set-Cookie': await context.session.commit(),
|
|
10
|
-
},
|
|
11
|
-
});
|
|
7
|
+
return redirect('/account');
|
|
12
8
|
}
|