@shopify/create-hydrogen 5.0.20 → 5.0.21
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/.cursor/rules/cookbook-recipe-subscriptions.mdc +921 -0
- package/dist/assets/hydrogen/starter/CHANGELOG.md +75 -16
- package/dist/assets/hydrogen/starter/app/components/CartLineItem.tsx +15 -0
- package/dist/assets/hydrogen/starter/app/components/CartMain.tsx +1 -1
- package/dist/assets/hydrogen/starter/app/components/ProductItem.tsx +44 -0
- package/dist/assets/hydrogen/starter/app/lib/redirect.ts +23 -0
- package/dist/assets/hydrogen/starter/app/root.tsx +45 -4
- package/dist/assets/hydrogen/starter/app/routes/_index.tsx +8 -23
- package/dist/assets/hydrogen/starter/app/routes/blogs.$blogHandle.$articleHandle.tsx +22 -2
- package/dist/assets/hydrogen/starter/app/routes/blogs.$blogHandle._index.tsx +4 -0
- package/dist/assets/hydrogen/starter/app/routes/collections.$handle.tsx +7 -41
- package/dist/assets/hydrogen/starter/app/routes/collections.all.tsx +11 -44
- package/dist/assets/hydrogen/starter/app/routes/pages.$handle.tsx +9 -1
- package/dist/assets/hydrogen/starter/app/routes/products.$handle.tsx +5 -1
- package/dist/assets/hydrogen/starter/app/routes.ts +4 -2
- package/dist/assets/hydrogen/starter/app/styles/app.css +15 -3
- package/dist/assets/hydrogen/starter/package.json +5 -5
- package/dist/assets/hydrogen/starter/storefrontapi.generated.d.ts +57 -36
- package/dist/create-app.js +2 -2
- package/package.json +1 -1
- package/dist/assets/hydrogen/starter/app/layout.tsx +0 -46
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import {flatRoutes} from '@remix-run/fs-routes';
|
|
2
|
-
import {
|
|
2
|
+
import {type RouteConfig} from '@remix-run/route-config';
|
|
3
3
|
import {hydrogenRoutes} from '@shopify/hydrogen';
|
|
4
4
|
|
|
5
5
|
export default hydrogenRoutes([
|
|
6
|
-
|
|
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;
|
|
@@ -27,12 +27,17 @@ img {
|
|
|
27
27
|
* components/Aside
|
|
28
28
|
* --------------------------------------------------
|
|
29
29
|
*/
|
|
30
|
+
@media (max-width: 45em) {
|
|
31
|
+
html:has(.overlay.expanded) {
|
|
32
|
+
overflow: hidden;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
30
36
|
aside {
|
|
31
37
|
background: var(--color-light);
|
|
32
38
|
box-shadow: 0 0 50px rgba(0, 0, 0, 0.3);
|
|
33
39
|
height: 100vh;
|
|
34
|
-
|
|
35
|
-
min-width: var(--aside-width);
|
|
40
|
+
width: min(var(--aside-width), 100vw);
|
|
36
41
|
position: fixed;
|
|
37
42
|
right: calc(-1 * var(--aside-width));
|
|
38
43
|
top: 0;
|
|
@@ -201,6 +206,11 @@ button.reset:hover:not(:has(> *)) {
|
|
|
201
206
|
margin-left: auto;
|
|
202
207
|
}
|
|
203
208
|
|
|
209
|
+
.header-ctas > * {
|
|
210
|
+
min-width: fit-content;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
|
|
204
214
|
/*
|
|
205
215
|
* --------------------------------------------------
|
|
206
216
|
* components/Footer
|
|
@@ -212,14 +222,16 @@ button.reset:hover:not(:has(> *)) {
|
|
|
212
222
|
}
|
|
213
223
|
|
|
214
224
|
.footer-menu {
|
|
215
|
-
|
|
225
|
+
justify-content: center;
|
|
216
226
|
display: flex;
|
|
227
|
+
flex-wrap: wrap;
|
|
217
228
|
grid-gap: 1rem;
|
|
218
229
|
padding: 1rem;
|
|
219
230
|
}
|
|
220
231
|
|
|
221
232
|
.footer-menu a {
|
|
222
233
|
color: var(--color-light);
|
|
234
|
+
min-width: fit-content;
|
|
223
235
|
}
|
|
224
236
|
|
|
225
237
|
/*
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "skeleton",
|
|
3
3
|
"private": true,
|
|
4
4
|
"sideEffects": false,
|
|
5
|
-
"version": "2025.1.
|
|
5
|
+
"version": "2025.1.7",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"build": "shopify hydrogen build --codegen",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"@remix-run/react": "^2.16.1",
|
|
18
18
|
"@remix-run/server-runtime": "^2.16.1",
|
|
19
19
|
"graphql": "^16.10.0",
|
|
20
|
-
"@shopify/hydrogen": "2025.1.
|
|
20
|
+
"@shopify/hydrogen": "2025.1.4",
|
|
21
21
|
"@shopify/remix-oxygen": "^2.0.12",
|
|
22
22
|
"graphql-tag": "^2.12.6",
|
|
23
23
|
"isbot": "^5.1.22",
|
|
@@ -32,9 +32,9 @@
|
|
|
32
32
|
"@remix-run/dev": "^2.16.1",
|
|
33
33
|
"@remix-run/fs-routes": "^2.16.1",
|
|
34
34
|
"@remix-run/route-config": "^2.16.1",
|
|
35
|
-
"@shopify/cli": "~3.
|
|
35
|
+
"@shopify/cli": "~3.78.1",
|
|
36
36
|
"@shopify/hydrogen-codegen": "^0.3.3",
|
|
37
|
-
"@shopify/mini-oxygen": "^3.1
|
|
37
|
+
"@shopify/mini-oxygen": "^3.2.1",
|
|
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",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"eslint-plugin-react-hooks": "^5.1.0",
|
|
56
56
|
"globals": "^15.14.0",
|
|
57
57
|
"typescript": "^5.2.2",
|
|
58
|
-
"vite": "^6.2.
|
|
58
|
+
"vite": "^6.2.4",
|
|
59
59
|
"vite-tsconfig-paths": "^4.3.1"
|
|
60
60
|
},
|
|
61
61
|
"engines": {
|
|
@@ -331,11 +331,9 @@ export type RecommendedProductFragment = Pick<
|
|
|
331
331
|
priceRange: {
|
|
332
332
|
minVariantPrice: Pick<StorefrontAPI.MoneyV2, 'amount' | 'currencyCode'>;
|
|
333
333
|
};
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
>;
|
|
338
|
-
};
|
|
334
|
+
featuredImage?: StorefrontAPI.Maybe<
|
|
335
|
+
Pick<StorefrontAPI.Image, 'id' | 'url' | 'altText' | 'width' | 'height'>
|
|
336
|
+
>;
|
|
339
337
|
};
|
|
340
338
|
|
|
341
339
|
export type RecommendedProductsQueryVariables = StorefrontAPI.Exact<{
|
|
@@ -353,14 +351,12 @@ export type RecommendedProductsQuery = {
|
|
|
353
351
|
'amount' | 'currencyCode'
|
|
354
352
|
>;
|
|
355
353
|
};
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
>;
|
|
363
|
-
};
|
|
354
|
+
featuredImage?: StorefrontAPI.Maybe<
|
|
355
|
+
Pick<
|
|
356
|
+
StorefrontAPI.Image,
|
|
357
|
+
'id' | 'url' | 'altText' | 'width' | 'height'
|
|
358
|
+
>
|
|
359
|
+
>;
|
|
364
360
|
}
|
|
365
361
|
>;
|
|
366
362
|
};
|
|
@@ -374,22 +370,29 @@ export type ArticleQueryVariables = StorefrontAPI.Exact<{
|
|
|
374
370
|
}>;
|
|
375
371
|
|
|
376
372
|
export type ArticleQuery = {
|
|
377
|
-
blog?: StorefrontAPI.Maybe<
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
373
|
+
blog?: StorefrontAPI.Maybe<
|
|
374
|
+
Pick<StorefrontAPI.Blog, 'handle'> & {
|
|
375
|
+
articleByHandle?: StorefrontAPI.Maybe<
|
|
376
|
+
Pick<
|
|
377
|
+
StorefrontAPI.Article,
|
|
378
|
+
'handle' | 'title' | 'contentHtml' | 'publishedAt'
|
|
379
|
+
> & {
|
|
380
|
+
author?: StorefrontAPI.Maybe<
|
|
381
|
+
Pick<StorefrontAPI.ArticleAuthor, 'name'>
|
|
382
|
+
>;
|
|
383
|
+
image?: StorefrontAPI.Maybe<
|
|
384
|
+
Pick<
|
|
385
|
+
StorefrontAPI.Image,
|
|
386
|
+
'id' | 'altText' | 'url' | 'width' | 'height'
|
|
387
|
+
>
|
|
388
|
+
>;
|
|
389
|
+
seo?: StorefrontAPI.Maybe<
|
|
390
|
+
Pick<StorefrontAPI.Seo, 'description' | 'title'>
|
|
391
|
+
>;
|
|
392
|
+
}
|
|
393
|
+
>;
|
|
394
|
+
}
|
|
395
|
+
>;
|
|
393
396
|
};
|
|
394
397
|
|
|
395
398
|
export type BlogQueryVariables = StorefrontAPI.Exact<{
|
|
@@ -407,7 +410,7 @@ export type BlogQueryVariables = StorefrontAPI.Exact<{
|
|
|
407
410
|
|
|
408
411
|
export type BlogQuery = {
|
|
409
412
|
blog?: StorefrontAPI.Maybe<
|
|
410
|
-
Pick<StorefrontAPI.Blog, 'title'> & {
|
|
413
|
+
Pick<StorefrontAPI.Blog, 'title' | 'handle'> & {
|
|
411
414
|
seo?: StorefrontAPI.Maybe<
|
|
412
415
|
Pick<StorefrontAPI.Seo, 'title' | 'description'>
|
|
413
416
|
>;
|
|
@@ -587,6 +590,24 @@ export type StoreCollectionsQuery = {
|
|
|
587
590
|
};
|
|
588
591
|
};
|
|
589
592
|
|
|
593
|
+
export type MoneyCollectionItemFragment = Pick<
|
|
594
|
+
StorefrontAPI.MoneyV2,
|
|
595
|
+
'amount' | 'currencyCode'
|
|
596
|
+
>;
|
|
597
|
+
|
|
598
|
+
export type CollectionItemFragment = Pick<
|
|
599
|
+
StorefrontAPI.Product,
|
|
600
|
+
'id' | 'handle' | 'title'
|
|
601
|
+
> & {
|
|
602
|
+
featuredImage?: StorefrontAPI.Maybe<
|
|
603
|
+
Pick<StorefrontAPI.Image, 'id' | 'altText' | 'url' | 'width' | 'height'>
|
|
604
|
+
>;
|
|
605
|
+
priceRange: {
|
|
606
|
+
minVariantPrice: Pick<StorefrontAPI.MoneyV2, 'amount' | 'currencyCode'>;
|
|
607
|
+
maxVariantPrice: Pick<StorefrontAPI.MoneyV2, 'amount' | 'currencyCode'>;
|
|
608
|
+
};
|
|
609
|
+
};
|
|
610
|
+
|
|
590
611
|
export type CatalogQueryVariables = StorefrontAPI.Exact<{
|
|
591
612
|
country?: StorefrontAPI.InputMaybe<StorefrontAPI.CountryCode>;
|
|
592
613
|
language?: StorefrontAPI.InputMaybe<StorefrontAPI.LanguageCode>;
|
|
@@ -637,7 +658,7 @@ export type PageQueryVariables = StorefrontAPI.Exact<{
|
|
|
637
658
|
|
|
638
659
|
export type PageQuery = {
|
|
639
660
|
page?: StorefrontAPI.Maybe<
|
|
640
|
-
Pick<StorefrontAPI.Page, 'id' | 'title' | 'body'> & {
|
|
661
|
+
Pick<StorefrontAPI.Page, 'handle' | 'id' | 'title' | 'body'> & {
|
|
641
662
|
seo?: StorefrontAPI.Maybe<
|
|
642
663
|
Pick<StorefrontAPI.Seo, 'description' | 'title'>
|
|
643
664
|
>;
|
|
@@ -1181,15 +1202,15 @@ interface GeneratedQueryTypes {
|
|
|
1181
1202
|
return: FeaturedCollectionQuery;
|
|
1182
1203
|
variables: FeaturedCollectionQueryVariables;
|
|
1183
1204
|
};
|
|
1184
|
-
'#graphql\n fragment RecommendedProduct on Product {\n id\n title\n handle\n priceRange {\n minVariantPrice {\n amount\n currencyCode\n }\n }\n
|
|
1205
|
+
'#graphql\n fragment RecommendedProduct on Product {\n id\n title\n handle\n priceRange {\n minVariantPrice {\n amount\n currencyCode\n }\n }\n featuredImage {\n id\n url\n altText\n width\n height\n }\n }\n query RecommendedProducts ($country: CountryCode, $language: LanguageCode)\n @inContext(country: $country, language: $language) {\n products(first: 4, sortKey: UPDATED_AT, reverse: true) {\n nodes {\n ...RecommendedProduct\n }\n }\n }\n': {
|
|
1185
1206
|
return: RecommendedProductsQuery;
|
|
1186
1207
|
variables: RecommendedProductsQueryVariables;
|
|
1187
1208
|
};
|
|
1188
|
-
'#graphql\n query Article(\n $articleHandle: String!\n $blogHandle: String!\n $country: CountryCode\n $language: LanguageCode\n ) @inContext(language: $language, country: $country) {\n blog(handle: $blogHandle) {\n articleByHandle(handle: $articleHandle) {\n title\n contentHtml\n publishedAt\n author: authorV2 {\n name\n }\n image {\n id\n altText\n url\n width\n height\n }\n seo {\n description\n title\n }\n }\n }\n }\n': {
|
|
1209
|
+
'#graphql\n query Article(\n $articleHandle: String!\n $blogHandle: String!\n $country: CountryCode\n $language: LanguageCode\n ) @inContext(language: $language, country: $country) {\n blog(handle: $blogHandle) {\n handle\n articleByHandle(handle: $articleHandle) {\n handle\n title\n contentHtml\n publishedAt\n author: authorV2 {\n name\n }\n image {\n id\n altText\n url\n width\n height\n }\n seo {\n description\n title\n }\n }\n }\n }\n': {
|
|
1189
1210
|
return: ArticleQuery;
|
|
1190
1211
|
variables: ArticleQueryVariables;
|
|
1191
1212
|
};
|
|
1192
|
-
'#graphql\n query Blog(\n $language: LanguageCode\n $blogHandle: String!\n $first: Int\n $last: Int\n $startCursor: String\n $endCursor: String\n ) @inContext(language: $language) {\n blog(handle: $blogHandle) {\n title\n seo {\n title\n description\n }\n articles(\n first: $first,\n last: $last,\n before: $startCursor,\n after: $endCursor\n ) {\n nodes {\n ...ArticleItem\n }\n pageInfo {\n hasPreviousPage\n hasNextPage\n hasNextPage\n endCursor\n startCursor\n }\n\n }\n }\n }\n fragment ArticleItem on Article {\n author: authorV2 {\n name\n }\n contentHtml\n handle\n id\n image {\n id\n altText\n url\n width\n height\n }\n publishedAt\n title\n blog {\n handle\n }\n }\n': {
|
|
1213
|
+
'#graphql\n query Blog(\n $language: LanguageCode\n $blogHandle: String!\n $first: Int\n $last: Int\n $startCursor: String\n $endCursor: String\n ) @inContext(language: $language) {\n blog(handle: $blogHandle) {\n title\n handle\n seo {\n title\n description\n }\n articles(\n first: $first,\n last: $last,\n before: $startCursor,\n after: $endCursor\n ) {\n nodes {\n ...ArticleItem\n }\n pageInfo {\n hasPreviousPage\n hasNextPage\n hasNextPage\n endCursor\n startCursor\n }\n\n }\n }\n }\n fragment ArticleItem on Article {\n author: authorV2 {\n name\n }\n contentHtml\n handle\n id\n image {\n id\n altText\n url\n width\n height\n }\n publishedAt\n title\n blog {\n handle\n }\n }\n': {
|
|
1193
1214
|
return: BlogQuery;
|
|
1194
1215
|
variables: BlogQueryVariables;
|
|
1195
1216
|
};
|
|
@@ -1205,11 +1226,11 @@ interface GeneratedQueryTypes {
|
|
|
1205
1226
|
return: StoreCollectionsQuery;
|
|
1206
1227
|
variables: StoreCollectionsQueryVariables;
|
|
1207
1228
|
};
|
|
1208
|
-
'#graphql\n query Catalog(\n $country: CountryCode\n $language: LanguageCode\n $first: Int\n $last: Int\n $startCursor: String\n $endCursor: String\n ) @inContext(country: $country, language: $language) {\n products(first: $first, last: $last, before: $startCursor, after: $endCursor) {\n nodes {\n ...
|
|
1229
|
+
'#graphql\n query Catalog(\n $country: CountryCode\n $language: LanguageCode\n $first: Int\n $last: Int\n $startCursor: String\n $endCursor: String\n ) @inContext(country: $country, language: $language) {\n products(first: $first, last: $last, before: $startCursor, after: $endCursor) {\n nodes {\n ...CollectionItem\n }\n pageInfo {\n hasPreviousPage\n hasNextPage\n startCursor\n endCursor\n }\n }\n }\n #graphql\n fragment MoneyCollectionItem on MoneyV2 {\n amount\n currencyCode\n }\n fragment CollectionItem on Product {\n id\n handle\n title\n featuredImage {\n id\n altText\n url\n width\n height\n }\n priceRange {\n minVariantPrice {\n ...MoneyCollectionItem\n }\n maxVariantPrice {\n ...MoneyCollectionItem\n }\n }\n }\n\n': {
|
|
1209
1230
|
return: CatalogQuery;
|
|
1210
1231
|
variables: CatalogQueryVariables;
|
|
1211
1232
|
};
|
|
1212
|
-
'#graphql\n query Page(\n $language: LanguageCode,\n $country: CountryCode,\n $handle: String!\n )\n @inContext(language: $language, country: $country) {\n page(handle: $handle) {\n id\n title\n body\n seo {\n description\n title\n }\n }\n }\n': {
|
|
1233
|
+
'#graphql\n query Page(\n $language: LanguageCode,\n $country: CountryCode,\n $handle: String!\n )\n @inContext(language: $language, country: $country) {\n page(handle: $handle) {\n handle\n id\n title\n body\n seo {\n description\n title\n }\n }\n }\n': {
|
|
1213
1234
|
return: PageQuery;
|
|
1214
1235
|
variables: PageQueryVariables;
|
|
1215
1236
|
};
|
package/dist/create-app.js
CHANGED
|
@@ -1435,7 +1435,7 @@ end
|
|
|
1435
1435
|
|
|
1436
1436
|
${jm.cyan(p)}
|
|
1437
1437
|
|
|
1438
|
-
This flag is required in non-interactive terminal environments, such as a CI environment, or when piping input from another process.`,"To resolve this, specify the option in the command, or run the command in an interactive environment such as your local terminal.")})}async resultWithEnvironment(a,o,p){let d=a.flags,h=this.environmentsFilename();if(!d.environment||!h)return a;let g=await ACe(d.environment,h,{from:d.path});if(!g)return a;let y=await super.parse(QAr(o),p),v=await super.parse(o,[...p||this.argv,...ZAr(g,o,y)]);return XAr(y.flags,v.flags,d.environment,g),v}};Tie.baseFlags={};async function YAr(s){await cie(()=>({cmd_all_verbose:s.verbose,cmd_all_path_override:s.path!==void 0,cmd_all_path_override_hash:s.path===void 0?void 0:b3e(s.path)}))}function XAr(s,a,o,p){let d={};for(let[g,y]of Object.entries(a)){let v=Object.prototype.hasOwnProperty.call(s,g),C=Object.prototype.hasOwnProperty.call(p,g);if(!v&&C){let w=g==="password"?`********${y.substr(-4)}`:y;d[g]=w}}if(Object.keys(d).length===0)return;let h=Object.entries(d).map(([g,y])=>`${g}: ${y}`);Lx({headline:["Using applicable flags from",{userInput:o},"environment:"],body:[{list:{items:h}}]})}function QAr(s){return s?.flags?{...s,flags:Object.fromEntries(Object.entries(s.flags).map(([a,o])=>{let p={...o};return delete p.default,[a,p]}))}:s}function ZAr(s,a,o){let p=[];for(let[d,h]of Object.entries(s)){let g=a?.flags&&Object.prototype.hasOwnProperty.call(a.flags,d),y=o.flags&&Object.prototype.hasOwnProperty.call(o.flags,d);if(g&&!y)if(typeof h=="boolean")if(h)p.push(`--${d}`);else throw new Pl(bg`Environments can only specify true for boolean flags. Attempted to set ${jm.yellow(d)} to false.`);else Array.isArray(h)?h.forEach(v=>p.push(`--${d}`,`${v}`)):p.push(`--${d}`,`${h}`)}return p}var PCe=Tie;var OS=xg(Vfe(),1);yi();var F1=xg(Vfe(),1);yi();yi();yi();import{fileURLToPath as NCe}from"node:url";yi();import{exec as eSr}from"node:child_process";import{promisify as tSr}from"node:util";var UE=tSr(eSr);function OCe(){let s=process.listeners("warning")[0];s&&(process.removeAllListeners("warning"),process.prependListener("warning",a=>{a.name!="ExperimentalWarning"&&s(a)}))}var Fie=new URL("../../..",import.meta.url).pathname,jD=Fie.endsWith("/hydrogen/packages/"),rde=jD?Fie:void 0,rSr="assets/hydrogen",nSr="starter",Tw="routes",tde;async function iSr(){if(tde??=await mie("package.json",{cwd:NCe(import.meta.url),type:"file"}),!tde)throw new Pl("Could not find assets directory","Please report this error.");return tde}async function Yy(s,...a){return el(em(await iSr()),process.env.SHOPIFY_UNIT_TEST?"assets":`dist/${rSr}`,s??"",...a)}async function _Y(s,a){a??=await E9();let o=new URL(`${a}/app${s?`/${s}`:""}`,import.meta.url);return o.protocol==="file:"?NCe(o):o.toString()}function E9(s=!!process.env.SHOPIFY_UNIT_TEST){return s?mY():Yy(nSr)}function mY(){if(!jD)throw new Pl("Trying to use skeleton source dir outside of Hydrogen monorepo.","Please report this error.");return el(em(Fie),"templates","skeleton")}async function nde(){let{stdout:s}=await UE("npm root"),a=s.trim();return!a&&jD&&(a=el(em(Fie),"node_modules")),a}var ICe=["tailwind","vanilla-extract","css-modules","postcss"];async function BCe(s,a,o,p=(d,h)=>d){let d=await Yy(s);return Promise.all(Object.entries(a).map(async([h,g])=>{let y=await d1(el(d,h));await H1(el(o,g),p(y,h))}))}async function LCe(s,a,o){let p=Object.values(s).map(h=>Sf(el(a,h)).then(g=>g?h:null)),d=(await Promise.all(p)).filter(Boolean);return!(d.length>0&&!o&&!await $E({message:`Some files already exist (${d.join(", ")}). Overwrite?`,defaultValue:!1}))}yi();yi();import{readdir as mkr}from"node:fs/promises";yi();var Qie=xg(XSe(),1);import*as QSe from"fs/promises";import*as ZSe from"path";var u1e={arrowParens:"always",singleQuote:!0,bracketSpacing:!1,trailingComma:"all"};async function dC(s=process.cwd()){let a=(await QSe.lstat(s)).isFile()?s:ZSe.resolve(s,"prettier.file");try{return await Qie.resolveConfig(a)||u1e}catch{return u1e}}async function Bw(s,a=u1e,o=""){let p=uie(o);return Qie.format(s,{parser:p===".tsx"||p===".ts"?"typescript":"babel",...a})}async function vS(s,a,o){let p=await o(await d1(s));if(typeof p=="string")return a&&(p=await Bw(p,a,s)),H1(s,p)}var gkr=["tsx","ts","jsx","js","mjs","cjs"];async function Dg(s,a,o=gkr){let p=await mkr(s);if(p.includes(a)){let d=n_(s,a);if(!await _ie(d))return{filepath:d};for(let h of["ts","js"]){let g=n_(s,`${a}/index.${h}`);if(await Sf(n_(s,g)))return{filepath:g,extension:h,astType:h}}}else for(let d of o){let h=`${a}.${d}`;if(p.includes(h)){let g=d==="mjs"||d==="cjs"?"js":d;return{filepath:n_(s,h),extension:d,astType:g}}}return{}}var e6e=Object.freeze(["dependencies","devDependencies","peerDependencies"]);async function QM(s,a,o){let p=await x9(el(a,"package.json")),d=await x9(el(s,"package.json")),h=new Set(["comment",...o?.ignoredKeys??[]]),g=Object.keys(d).filter(v=>!e6e.includes(v));for(let v of g){if(h.has(v))continue;let C=d[v],w=p[v],k=Array.isArray(C)&&Array.isArray(w)?[...w,...C]:typeof C=="object"&&typeof w=="object"?{...w,...C}:C;p[v]=k}let y=Object.entries(p.dependencies||{}).find(([v])=>v.startsWith("@remix-run/"))?.[1];for(let v of e6e)h.has(v)||d[v]&&(p[v]=[...new Set([...Object.keys(p[v]??{}),...Object.keys(d[v]??{})])].sort().reduce((C,w)=>{let k=d[v]?.[w]??p[v]?.[w];return w.startsWith("@remix-run/")&&y&&(k=y),C[w]=k,C},{}));await V3e(a,o?.onResult?.(p)??p)}async function t6e(s,a){let p=(await d1(el(s,"tsconfig.json"))).match(/"types": \[(.*?)\]/)?.[1];p&&vS(el(a,"tsconfig.json"),!1,d=>d.replace(/"types":\s*\[[^\]]*\]/,`"types": [${p}]`))}yi();yi();async function wY(s){let a=await import("@ast-grep/napi");if(!(s in a))throw new Error(`Wrong language for AST: ${s}`);return a[s]}async function r6e(s,a,o){let{filepath:p,astType:d}=await Dg(s,"
|
|
1438
|
+
This flag is required in non-interactive terminal environments, such as a CI environment, or when piping input from another process.`,"To resolve this, specify the option in the command, or run the command in an interactive environment such as your local terminal.")})}async resultWithEnvironment(a,o,p){let d=a.flags,h=this.environmentsFilename();if(!d.environment||!h)return a;let g=await ACe(d.environment,h,{from:d.path});if(!g)return a;let y=await super.parse(QAr(o),p),v=await super.parse(o,[...p||this.argv,...ZAr(g,o,y)]);return XAr(y.flags,v.flags,d.environment,g),v}};Tie.baseFlags={};async function YAr(s){await cie(()=>({cmd_all_verbose:s.verbose,cmd_all_path_override:s.path!==void 0,cmd_all_path_override_hash:s.path===void 0?void 0:b3e(s.path)}))}function XAr(s,a,o,p){let d={};for(let[g,y]of Object.entries(a)){let v=Object.prototype.hasOwnProperty.call(s,g),C=Object.prototype.hasOwnProperty.call(p,g);if(!v&&C){let w=g==="password"?`********${y.substr(-4)}`:y;d[g]=w}}if(Object.keys(d).length===0)return;let h=Object.entries(d).map(([g,y])=>`${g}: ${y}`);Lx({headline:["Using applicable flags from",{userInput:o},"environment:"],body:[{list:{items:h}}]})}function QAr(s){return s?.flags?{...s,flags:Object.fromEntries(Object.entries(s.flags).map(([a,o])=>{let p={...o};return delete p.default,[a,p]}))}:s}function ZAr(s,a,o){let p=[];for(let[d,h]of Object.entries(s)){let g=a?.flags&&Object.prototype.hasOwnProperty.call(a.flags,d),y=o.flags&&Object.prototype.hasOwnProperty.call(o.flags,d);if(g&&!y)if(typeof h=="boolean")if(h)p.push(`--${d}`);else throw new Pl(bg`Environments can only specify true for boolean flags. Attempted to set ${jm.yellow(d)} to false.`);else Array.isArray(h)?h.forEach(v=>p.push(`--${d}`,`${v}`)):p.push(`--${d}`,`${h}`)}return p}var PCe=Tie;var OS=xg(Vfe(),1);yi();var F1=xg(Vfe(),1);yi();yi();yi();import{fileURLToPath as NCe}from"node:url";yi();import{exec as eSr}from"node:child_process";import{promisify as tSr}from"node:util";var UE=tSr(eSr);function OCe(){let s=process.listeners("warning")[0];s&&(process.removeAllListeners("warning"),process.prependListener("warning",a=>{a.name!="ExperimentalWarning"&&s(a)}))}var Fie=new URL("../../..",import.meta.url).pathname,jD=Fie.endsWith("/hydrogen/packages/"),rde=jD?Fie:void 0,rSr="assets/hydrogen",nSr="starter",Tw="routes",tde;async function iSr(){if(tde??=await mie("package.json",{cwd:NCe(import.meta.url),type:"file"}),!tde)throw new Pl("Could not find assets directory","Please report this error.");return tde}async function Yy(s,...a){return el(em(await iSr()),process.env.SHOPIFY_UNIT_TEST?"assets":`dist/${rSr}`,s??"",...a)}async function _Y(s,a){a??=await E9();let o=new URL(`${a}/app${s?`/${s}`:""}`,import.meta.url);return o.protocol==="file:"?NCe(o):o.toString()}function E9(s=!!process.env.SHOPIFY_UNIT_TEST){return s?mY():Yy(nSr)}function mY(){if(!jD)throw new Pl("Trying to use skeleton source dir outside of Hydrogen monorepo.","Please report this error.");return el(em(Fie),"templates","skeleton")}async function nde(){let{stdout:s}=await UE("npm root"),a=s.trim();return!a&&jD&&(a=el(em(Fie),"node_modules")),a}var ICe=["tailwind","vanilla-extract","css-modules","postcss"];async function BCe(s,a,o,p=(d,h)=>d){let d=await Yy(s);return Promise.all(Object.entries(a).map(async([h,g])=>{let y=await d1(el(d,h));await H1(el(o,g),p(y,h))}))}async function LCe(s,a,o){let p=Object.values(s).map(h=>Sf(el(a,h)).then(g=>g?h:null)),d=(await Promise.all(p)).filter(Boolean);return!(d.length>0&&!o&&!await $E({message:`Some files already exist (${d.join(", ")}). Overwrite?`,defaultValue:!1}))}yi();yi();import{readdir as mkr}from"node:fs/promises";yi();var Qie=xg(XSe(),1);import*as QSe from"fs/promises";import*as ZSe from"path";var u1e={arrowParens:"always",singleQuote:!0,bracketSpacing:!1,trailingComma:"all"};async function dC(s=process.cwd()){let a=(await QSe.lstat(s)).isFile()?s:ZSe.resolve(s,"prettier.file");try{return await Qie.resolveConfig(a)||u1e}catch{return u1e}}async function Bw(s,a=u1e,o=""){let p=uie(o);return Qie.format(s,{parser:p===".tsx"||p===".ts"?"typescript":"babel",...a})}async function vS(s,a,o){let p=await o(await d1(s));if(typeof p=="string")return a&&(p=await Bw(p,a,s)),H1(s,p)}var gkr=["tsx","ts","jsx","js","mjs","cjs"];async function Dg(s,a,o=gkr){let p=await mkr(s);if(p.includes(a)){let d=n_(s,a);if(!await _ie(d))return{filepath:d};for(let h of["ts","js"]){let g=n_(s,`${a}/index.${h}`);if(await Sf(n_(s,g)))return{filepath:g,extension:h,astType:h}}}else for(let d of o){let h=`${a}.${d}`;if(p.includes(h)){let g=d==="mjs"||d==="cjs"?"js":d;return{filepath:n_(s,h),extension:d,astType:g}}}return{}}var e6e=Object.freeze(["dependencies","devDependencies","peerDependencies"]);async function QM(s,a,o){let p=await x9(el(a,"package.json")),d=await x9(el(s,"package.json")),h=new Set(["comment",...o?.ignoredKeys??[]]),g=Object.keys(d).filter(v=>!e6e.includes(v));for(let v of g){if(h.has(v))continue;let C=d[v],w=p[v],k=Array.isArray(C)&&Array.isArray(w)?[...w,...C]:typeof C=="object"&&typeof w=="object"?{...w,...C}:C;p[v]=k}let y=Object.entries(p.dependencies||{}).find(([v])=>v.startsWith("@remix-run/"))?.[1];for(let v of e6e)h.has(v)||d[v]&&(p[v]=[...new Set([...Object.keys(p[v]??{}),...Object.keys(d[v]??{})])].sort().reduce((C,w)=>{let k=d[v]?.[w]??p[v]?.[w];return w.startsWith("@remix-run/")&&y&&(k=y),C[w]=k,C},{}));await V3e(a,o?.onResult?.(p)??p)}async function t6e(s,a){let p=(await d1(el(s,"tsconfig.json"))).match(/"types": \[(.*?)\]/)?.[1];p&&vS(el(a,"tsconfig.json"),!1,d=>d.replace(/"types":\s*\[[^\]]*\]/,`"types": [${p}]`))}yi();yi();async function wY(s){let a=await import("@ast-grep/napi");if(!(s in a))throw new Error(`Wrong language for AST: ${s}`);return a[s]}async function r6e(s,a,o){let{filepath:p,astType:d}=await Dg(s,"root");if(!p||!d)throw new Pl(`Could not find root file in ${s}`);await vS(p,a,async h=>{let g=`import ${o.isDefault?o.name:`{${o.name}}`} from '${(o.isAbsolute?"":"./")+o.path}';`;if(h.includes(g.split("from")[0]))return;let v=(await wY(d)).parse(h).root(),C=v.findAll({rule:{kind:"import_statement"}}).reverse(),w=C.find(q=>q.text().includes(".css"))||C.shift(),k=v.find({rule:{kind:"jsx_element",regex:"resetStyles",has:{kind:"jsx_opening_element",has:{kind:"identifier",pattern:"link"}}}});if(!w||!k)throw new Pl('Could not find a "links" export in root file. Please add one and try again.');let N=w.text(),T=k.text(),P=o.isConditional?`{${o.name} && <link rel="stylesheet" href={${o.name}}></link>}`:`<link rel="stylesheet" href={${o.name}}></link>`;return h.replace(N,N+`
|
|
1439
1439
|
`+g).replace(T,P+`
|
|
1440
1440
|
`+T)})}async function Zie(s,a,o,p){let{filepath:d,astType:h}=await Dg(s,"vite.config");if(!d||!h)throw new Pl(`Could not find vite.config file in ${s}`);await vS(d,a,async g=>{let y=`import ${o.isDefault?o.name:`{${o.name}}`} from '${o.path}';`;if(new RegExp(`['"]${o.path.replace("/","\\/")}['"]`).test(g))return;let C=(await wY(h)).parse(g).root(),w=C.findAll({rule:{kind:"import_statement"}}).pop(),k=C.find(ykr);if(!w||!k)throw new Pl('Could not find a "plugins" key in Vite config file. Please add one and try again.');let N=w.text(),T=k.text(),P=`${o.name}(${p?JSON.stringify(p):""})`;return g.replace(N,N+`
|
|
1441
1441
|
`+y).replace(T,T.replace("[",`[${P},`))})}var ykr={rule:{pattern:"[$$$]",inside:{kind:"pair",stopBy:"neighbor",has:{field:"key",regex:"^plugins$",stopBy:"neighbor"},inside:{kind:"object",stopBy:"neighbor",all:[{inside:{kind:"export_statement",regex:"export default",stopBy:"end"}},{not:{inside:{kind:"object",stopBy:"end"}}}]}}}};var n6e="styles/tailwind.css";async function i6e({rootDirectory:s,appDirectory:a},o=!1){let p=LD(s,a),d={"tailwind.css":el(p,n6e)};if(!await LCe(d,a,o)){lY("Skipping CSS setup as some files already exist. You may use `--force` or `-f` to override it.");return}return{workPromise:Promise.all([QM(await Yy("tailwind"),s),BCe("tailwind",d,s),dC(s).then(g=>Promise.all([r6e(a,g,{name:"tailwindCss",path:`${n6e}?url`,isDefault:!0}),Zie(s,g,{name:"tailwindcss",path:"@tailwindcss/vite",isDefault:!0})]))]),generatedAssets:Object.values(d),needsInstallDeps:!0}}yi();async function s6e({rootDirectory:s}){return{workPromise:Promise.all([QM(await Yy("vanilla-extract"),s),dC(s).then(o=>Zie(s,o,{path:"@vanilla-extract/vite-plugin",name:"vanillaExtractPlugin",isDefault:!1}))]),generatedAssets:[],needsInstallDeps:!0}}var ZM=[...ICe,"none"],TY={tailwind:"Tailwind v4","vanilla-extract":"Vanilla Extract","css-modules":"CSS Modules",postcss:"PostCSS"};function a6e(s,a,o){switch(s){case"tailwind":return i6e(a,o);case"vanilla-extract":return s6e(a);case"postcss":case"css-modules":return{workPromise:Promise.resolve(),generatedAssets:[],needsInstallDeps:!1};default:throw new Error("Unknown strategy")}}async function o6e(s){let a=Object.entries({...TY,...s?.extraChoices});return RD({message:"Select a styling library",...s,choices:a.map(([o,p])=>({value:o,label:p})),defaultValue:"tailwind"})}yi();yi();yi();yi();async function Lw(s,a,o=!0){let{transpileTs:p}=await import("./morph-3JSBLNUD.js");return p(s,a,o)}yi();var u6e={checkJs:!1,target:"ES2022",module:"ES2022",moduleResolution:"bundler",baseUrl:".",paths:{"~/*":["app/*"]}},vkr=new Set(["noLib","target","module","moduleResolution","checkJs","experimentalDecorators","allowSyntheticDefaultImports","baseUrl","paths",...Object.keys(u6e)]);function xkr(s,a=!1){let o={compilerOptions:{...u6e}};if(s.include&&(o.include=s.include.filter(p=>a||!p.endsWith(".d.ts")).map(p=>p.replace(/(?<!\.d)\.ts(x?)$/,".js$1"))),s.compilerOptions)for(let p of vkr)s.compilerOptions[p]!==void 0&&(o.compilerOptions[p]=s.compilerOptions[p]);return o}async function c1e(s,a=!0){let o=el(s,"app/routes.ts"),d=(await d1(o)).replace("./layout.tsx","./layout.jsx");await H1(o,d);let h=await x3e("**/*.+(ts|tsx)",{absolute:!0,cwd:s,dot:!0,ignore:["**/node_modules/**"]}),g=await dC();for(let y of h){if(y.endsWith(".d.ts")){a||await pY(y);continue}let v=await d1(y),C=await Bw(await Lw(v,y,a),g);await pY(y),await H1(y.replace(/\.ts(x?)$/,".js$1"),C)}try{let y=el(s,"remix.config.js"),v=await d1(y);v=v.replace(/\/server\.ts/gim,"/server.js"),await H1(y,v)}catch(y){f1(`Could not change TS extensions in remix.config.js:
|
|
@@ -1549,7 +1549,7 @@ if (!$profileContent -or $profileContent -NotLike '*Invoke-Local-H2*') {
|
|
|
1549
1549
|
productionUrl
|
|
1550
1550
|
}
|
|
1551
1551
|
}
|
|
1552
|
-
`;async function m5e(s){let{hydrogenStorefronts:a}=await uq(nNr,s);return a.map(o=>({...o,parsedId:_5e(o.id)}))}var Fhe={js:"JavaScript",ts:"TypeScript"};async function y5e(s,a,o){let p=o??await p6e({abortSignal:s.signal,extraChoices:{none:"Set up later "+qE.dim(`(run \`${a} setup markets\`)`)}}),d=p==="none"?void 0:p;return{i18nStrategy:d,setupI18n:async h=>{d&&await l6e(d,h)}}}async function v5e(s,a){let o=a===!0?"all":a===!1?[]:await h5e({abortSignal:s.signal}),p=o==="all"||o.length>0;return{needsRouteGeneration:p,setupRoutes:async(d,h,g)=>{if(p)return(await f5e({routeName:o,directory:d,force:!0,typescript:h==="ts",localePrefix:g?.i18nStrategy==="subfolders"?"locale":!1,signal:s.signal,...g},{rootDirectory:d,appDirectory:el(d,"app")})).routeGroups}}}function x5e(s){return Promise.all(["routes.ts","
|
|
1552
|
+
`;async function m5e(s){let{hydrogenStorefronts:a}=await uq(nNr,s);return a.map(o=>({...o,parsedId:_5e(o.id)}))}var Fhe={js:"JavaScript",ts:"TypeScript"};async function y5e(s,a,o){let p=o??await p6e({abortSignal:s.signal,extraChoices:{none:"Set up later "+qE.dim(`(run \`${a} setup markets\`)`)}}),d=p==="none"?void 0:p;return{i18nStrategy:d,setupI18n:async h=>{d&&await l6e(d,h)}}}async function v5e(s,a){let o=a===!0?"all":a===!1?[]:await h5e({abortSignal:s.signal}),p=o==="all"||o.length>0;return{needsRouteGeneration:p,setupRoutes:async(d,h,g)=>{if(p)return(await f5e({routeName:o,directory:d,force:!0,typescript:h==="ts",localePrefix:g?.i18nStrategy==="subfolders"?"locale":!1,signal:s.signal,...g},{rootDirectory:d,appDirectory:el(d,"app")})).routeGroups}}}function x5e(s){return Promise.all(["routes.ts","root","entry.server","entry.client","../server.ts"].map(a=>khe(a,s)))}async function b5e(s,a,o){return a===C2?{}:o??await $E({confirmationMessage:"Yes",cancellationMessage:"No",message:["Create a global",{command:C2},"alias to run commands instead of",{command:a},"?"],abortSignal:s.signal})?{createShortcut:async()=>{try{return(await r5e()).length>0}catch(d){return f1("Failed to create shortcut."+(d?.stack??d?.message??d)),!1}},showShortcutBanner:()=>Lx({body:`You'll need to restart your terminal session to make \`${C2}\` alias available.`})}:{}}async function D5e(s){Ise(!0);let{session:a,config:o}=await JTe();zTe(o);let p=await m5e(a),d=await aNr(p),h;return d?h=d.title:h=await die({message:"New storefront name",defaultValue:WTe(o.shopName),abortSignal:s.signal}),{...o,id:d?.id,title:h,session:a}}async function aNr(s){let a=[{label:"Create a new storefront",value:null},...s.map(({id:p,title:d,productionUrl:h})=>({label:`${d} (${h})`,value:p}))];if(a.length===1)return;let o=await RD({message:"Select a Hydrogen storefront to link",choices:a});return o?s.find(({id:p})=>p===o):void 0}async function Lse({storefrontInfo:s,controller:a,force:o,path:p}){let d=s&&pie(s.title),h=p??d??await die({message:"Where would you like to create your storefront?",defaultValue:"hydrogen-storefront",abortSignal:a.signal}),g=n_(process.cwd(),h);if(await g5e(g)){if(!o&&d&&(h=await die({message:`There's already a folder called \`${d}\`. Where do you want to create the app?`,defaultValue:d,abortSignal:a.signal}),g=n_(process.cwd(),h),await g5e(g)||(o=!0)),!o&&!await $E({message:`The directory ${qE.cyan(h)} is not empty. Do you want to delete the existing files and continue?`,defaultValue:!1,abortSignal:a.signal})){Lx({body:`Destination path ${qE.cyan(h)} already exists and is not an empty directory. You may use \`--force\` or \`-f\` to override it.`});return}await RM(g,{force:!0})}return{name:BM(h),location:h,directory:g,storefrontTitle:s?.title}}async function Rse(s,a,o){let p=o??await RD({message:"Select a language",choices:[{label:"JavaScript",value:"js"},{label:"TypeScript",value:"ts"}],defaultValue:"js",abortSignal:a.signal});return{language:p,async transpileProject(){p!=="ts"&&await c1e(s)}}}async function E5e(s,a,o){let p=o??await o6e({abortSignal:a.signal,extraChoices:{none:"Skip and set up later"}}),d=p==="none"?void 0:p;return{cssStrategy:d,async setupCss(){if(d){if(d==="postcss"||d==="css-modules")return;let h=await a6e(d,{rootDirectory:s,appDirectory:el(s,"app")},!0);h&&await h.workPromise}}}}async function jse(s,a,o,p){let d=o??yie(),h="npm";if(p!==!1)if(d==="unknown"){let g=await RD({message:"Select package manager to install dependencies",choices:[{label:"NPM",value:"npm"},{label:"PNPM",value:"pnpm"},{label:"Yarn v1",value:"yarn"},{label:"Skip and install later",value:"no"}],defaultValue:"npm",abortSignal:a.signal});g==="no"?p=!1:(h=g,p=!0)}else p===void 0&&(h=d,p=await $E({message:`Install dependencies with ${d}?`,confirmationMessage:"Yes",cancellationMessage:"No",abortSignal:a.signal}));return jD&&(await gS(el(mY(),".npmrc"),el(s,".npmrc")).catch(()=>{}),p||await sNr(await nde(),el(s,"node_modules")).catch(()=>{})),{packageManager:h,shouldInstallDeps:p,installDeps:p?async()=>{await $3e({directory:s,packageManager:h,args:[],signal:a.signal})}:()=>{}}}var oNr=`
|
|
1553
1553
|
node_modules
|
|
1554
1554
|
/.cache
|
|
1555
1555
|
/build
|
package/package.json
CHANGED
|
@@ -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
|
-
}
|