@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.
@@ -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;
@@ -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
- max-width: var(--aside-width);
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
- align-items: center;
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",
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.3",
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.77.1",
35
+ "@shopify/cli": "~3.78.1",
36
36
  "@shopify/hydrogen-codegen": "^0.3.3",
37
- "@shopify/mini-oxygen": "^3.1.2",
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.0",
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
- images: {
335
- nodes: Array<
336
- Pick<StorefrontAPI.Image, 'id' | 'url' | 'altText' | 'width' | 'height'>
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
- images: {
357
- nodes: Array<
358
- Pick<
359
- StorefrontAPI.Image,
360
- 'id' | 'url' | 'altText' | 'width' | 'height'
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
- articleByHandle?: StorefrontAPI.Maybe<
379
- Pick<StorefrontAPI.Article, 'title' | 'contentHtml' | 'publishedAt'> & {
380
- author?: StorefrontAPI.Maybe<Pick<StorefrontAPI.ArticleAuthor, 'name'>>;
381
- image?: StorefrontAPI.Maybe<
382
- Pick<
383
- StorefrontAPI.Image,
384
- 'id' | 'altText' | 'url' | 'width' | 'height'
385
- >
386
- >;
387
- seo?: StorefrontAPI.Maybe<
388
- Pick<StorefrontAPI.Seo, 'description' | 'title'>
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 images(first: 1) {\n nodes {\n id\n url\n altText\n width\n height\n }\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': {
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 ...ProductItem\n }\n pageInfo {\n hasPreviousPage\n hasNextPage\n startCursor\n endCursor\n }\n }\n }\n #graphql\n fragment MoneyProductItem on MoneyV2 {\n amount\n currencyCode\n }\n fragment ProductItem 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 ...MoneyProductItem\n }\n maxVariantPrice {\n ...MoneyProductItem\n }\n }\n }\n\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
  };
@@ -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,"layout");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+`
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","layout.tsx","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=`
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
@@ -5,7 +5,7 @@
5
5
  "@shopify:registry": "https://registry.npmjs.org"
6
6
  },
7
7
  "license": "MIT",
8
- "version": "5.0.20",
8
+ "version": "5.0.21",
9
9
  "type": "module",
10
10
  "repository": {
11
11
  "type": "git",
@@ -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
- }