@shopify/cli 3.90.1 → 3.91.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{acorn-45LE5Z2A.js → acorn-WDTBS4B3.js} +2 -2
- package/dist/{angular-Z5FPQPLR.js → angular-WLPEGHXZ.js} +4 -4
- package/dist/assets/hydrogen/starter/.graphqlrc.ts +4 -2
- package/dist/assets/hydrogen/starter/CHANGELOG.md +172 -0
- package/dist/assets/hydrogen/starter/app/components/CartLineItem.tsx +67 -38
- package/dist/assets/hydrogen/starter/app/components/CartMain.tsx +45 -7
- package/dist/assets/hydrogen/starter/app/components/CartSummary.tsx +20 -38
- package/dist/assets/hydrogen/starter/app/components/MockShopNotice.tsx +20 -0
- package/dist/assets/hydrogen/starter/app/entry.client.tsx +2 -3
- package/dist/assets/hydrogen/starter/app/lib/fragments.ts +8 -0
- package/dist/assets/hydrogen/starter/app/routes/_index.tsx +4 -5
- package/dist/assets/hydrogen/starter/app/routes/account.addresses.tsx +12 -12
- package/dist/assets/hydrogen/starter/app/routes/account.tsx +4 -7
- package/dist/assets/hydrogen/starter/app/routes/account_.login.tsx +10 -0
- package/dist/assets/hydrogen/starter/app/routes/blogs.$blogHandle._index.tsx +2 -9
- package/dist/assets/hydrogen/starter/app/routes/blogs._index.tsx +1 -4
- package/dist/assets/hydrogen/starter/app/routes/cart.tsx +3 -11
- package/dist/assets/hydrogen/starter/app/routes/collections.all.tsx +1 -3
- package/dist/assets/hydrogen/starter/app/routes/pages.$handle.tsx +2 -8
- package/dist/assets/hydrogen/starter/app/routes/policies.$handle.tsx +1 -4
- package/dist/assets/hydrogen/starter/app/routes/policies._index.tsx +1 -1
- package/dist/assets/hydrogen/starter/app/routes/products.$handle.tsx +2 -9
- package/dist/assets/hydrogen/starter/app/routes/search.tsx +18 -12
- package/dist/assets/hydrogen/starter/app/styles/app.css +72 -1
- package/dist/assets/hydrogen/starter/eslint.config.js +1 -0
- package/dist/assets/hydrogen/starter/guides/predictiveSearch/predictiveSearch.md +3 -3
- package/dist/assets/hydrogen/starter/guides/search/search.md +1 -1
- package/dist/assets/hydrogen/starter/package.json +14 -13
- package/dist/assets/hydrogen/starter/server.ts +5 -7
- package/dist/assets/hydrogen/starter/storefrontapi.generated.d.ts +89 -0
- package/dist/{babel-TRRZ6QQY.js → babel-LQYCV4NA.js} +2 -7
- package/dist/{brotli-2OKV26Y6.js → brotli-6CC7WD4Z.js} +1 -2
- package/dist/{chunk-SGU7BPE4.js → chunk-2EQNSO7C.js} +3 -3
- package/dist/{chunk-PAU7LKSJ.js → chunk-2YAGQHB2.js} +3 -3
- package/dist/{chunk-OZPZBNSB.js → chunk-463KYFYO.js} +2 -2
- package/dist/{chunk-IEPPQIPW.js → chunk-54FE2FGU.js} +2 -2
- package/dist/{chunk-EFOOQV72.js → chunk-56ELYGPH.js} +2 -2
- package/dist/{chunk-6ONJ77I7.js → chunk-5JYQJQ2E.js} +2 -2
- package/dist/chunk-5ZDTGPNX.js +28 -0
- package/dist/{chunk-6ONJEX7Y.js → chunk-6NVYATES.js} +2 -2
- package/dist/chunk-77BDQRQW.js +90 -0
- package/dist/{chunk-HMDWNGIV.js → chunk-A27P5CF7.js} +211 -103
- package/dist/{chunk-4BBQTKIZ.js → chunk-A2CZGTAP.js} +27763 -25681
- package/dist/{chunk-TIYR37XP.js → chunk-ATQVKUJC.js} +4 -4
- package/dist/{chunk-3GXB4ZRP.js → chunk-CE4S2SGM.js} +10 -10
- package/dist/{chunk-WC5EDB4Z.js → chunk-CEUL3KX5.js} +1190 -144
- package/dist/{chunk-2TMOMDXO.js → chunk-DR5R5UTE.js} +6 -6
- package/dist/{chunk-IYNLJNFT.js → chunk-DUNGALP3.js} +3 -3
- package/dist/{chunk-TGDLXF4K.js → chunk-E44JKFB6.js} +2 -2
- package/dist/{chunk-5SJCPOBW.js → chunk-E4GUDBAR.js} +417 -387
- package/dist/{chunk-C5STUYKR.js → chunk-FKP67FZI.js} +3 -3
- package/dist/{chunk-ZZNQWJUM.js → chunk-HAG3HJ2V.js} +10 -10
- package/dist/{chunk-PUMWL67K.js → chunk-HOIU6WRE.js} +3 -3
- package/dist/{chunk-GPKHDSF5.js → chunk-HTGTTXQL.js} +24 -26
- package/dist/{chunk-3VKS4374.js → chunk-I23GZAC4.js} +15 -17
- package/dist/chunk-ITTNM7I4.js +23 -0
- package/dist/chunk-IUKBWIQY.js +39 -0
- package/dist/{chunk-H3SSAPRP.js → chunk-K45ALTZ7.js} +3 -3
- package/dist/chunk-K52ORY26.js +78 -0
- package/dist/{prettier-2ITB6I34.js → chunk-KV3364EL.js} +43 -42
- package/dist/{chunk-4TOZOCIV.js → chunk-LFMBIRVC.js} +3 -3
- package/dist/{chunk-OTD3FRPC.js → chunk-NYP3N62G.js} +2 -2
- package/dist/chunk-OIUDJFV2.js +309 -0
- package/dist/{chunk-HV4MPORZ.js → chunk-PCNR4TMY.js} +5 -5
- package/dist/{chunk-SG2A4CTL.js → chunk-QFO7QSBW.js} +4 -4
- package/dist/{chunk-UHBL2XEG.js → chunk-R622IPZN.js} +3 -3
- package/dist/{chunk-X7CGUWBF.js → chunk-RKFRXKFE.js} +3 -3
- package/dist/{chunk-WYVKPOTO.js → chunk-RLJICWO6.js} +4 -4
- package/dist/chunk-SJXHR42U.js +36 -0
- package/dist/{chunk-CYPBBNM2.js → chunk-SUFC4ISB.js} +6 -6
- package/dist/{chunk-3AF66HDC.js → chunk-SVV4RJVX.js} +4 -4
- package/dist/chunk-TH7ZYYDZ.js +20868 -0
- package/dist/{chunk-J2CFMYG5.js → chunk-TY5YKCUW.js} +5 -5
- package/dist/{chunk-XD3LXUGW.js → chunk-VBBBCVMH.js} +2 -2
- package/dist/chunk-VRUH5BDH.js +51 -0
- package/dist/{chunk-7FIBLDM2.js → chunk-VUYVHHZY.js} +3 -3
- package/dist/{chunk-KC6KOCJ5.js → chunk-WDYPK6VH.js} +7 -7
- package/dist/{chunk-JRFL7VGC.js → chunk-XDCBS7SY.js} +3 -3
- package/dist/{chunk-6MYWZ7MP.js → chunk-Z5FK5H2M.js} +8 -27
- package/dist/{chunk-RHYTM4FE.js → chunk-ZLV2A27J.js} +2 -2
- package/dist/cli/commands/auth/login.js +14 -16
- package/dist/cli/commands/auth/login.test.js +16 -18
- package/dist/cli/commands/auth/logout.js +14 -16
- package/dist/cli/commands/auth/logout.test.js +17 -19
- package/dist/cli/commands/cache/clear.js +15 -16
- package/dist/cli/commands/debug/command-flags.js +14 -16
- package/dist/cli/commands/docs/generate.js +14 -16
- package/dist/cli/commands/docs/generate.test.js +15 -17
- package/dist/cli/commands/doctor-release/doctor-release.d.ts +6 -0
- package/dist/cli/commands/doctor-release/doctor-release.js +27 -0
- package/dist/cli/commands/doctor-release/theme/index.d.ts +14 -0
- package/dist/cli/commands/doctor-release/theme/index.js +33 -0
- package/dist/cli/commands/help.js +14 -16
- package/dist/cli/commands/kitchen-sink/async.js +15 -17
- package/dist/cli/commands/kitchen-sink/async.test.js +16 -18
- package/dist/cli/commands/kitchen-sink/index.js +17 -19
- package/dist/cli/commands/kitchen-sink/index.test.js +20 -22
- package/dist/cli/commands/kitchen-sink/prompts.js +15 -17
- package/dist/cli/commands/kitchen-sink/prompts.test.js +16 -18
- package/dist/cli/commands/kitchen-sink/static.js +15 -17
- package/dist/cli/commands/kitchen-sink/static.test.js +16 -18
- package/dist/cli/commands/notifications/generate.js +15 -17
- package/dist/cli/commands/notifications/list.js +15 -17
- package/dist/cli/commands/search.js +15 -17
- package/dist/cli/commands/upgrade.js +15 -17
- package/dist/cli/commands/upgrade.test.js +1 -1
- package/dist/cli/commands/version.js +15 -17
- package/dist/cli/commands/version.test.js +16 -18
- package/dist/cli/services/commands/notifications.js +14 -14
- package/dist/cli/services/commands/search.js +8 -9
- package/dist/cli/services/commands/search.test.js +9 -10
- package/dist/cli/services/commands/version.js +9 -10
- package/dist/cli/services/commands/version.test.js +11 -12
- package/dist/cli/services/doctor-release/context.d.ts +16 -0
- package/dist/cli/services/doctor-release/context.js +9 -0
- package/dist/cli/services/doctor-release/theme/runner.d.ts +7 -0
- package/dist/cli/services/doctor-release/theme/runner.js +24 -0
- package/dist/cli/services/doctor-release/theme/tests/init.d.ts +11 -0
- package/dist/cli/services/doctor-release/theme/tests/init.js +21 -0
- package/dist/cli/services/doctor-release/theme/tests/push.d.ts +10 -0
- package/dist/cli/services/doctor-release/theme/tests/push.js +21 -0
- package/dist/cli/services/kitchen-sink/async.js +8 -9
- package/dist/cli/services/kitchen-sink/prompts.js +8 -9
- package/dist/cli/services/kitchen-sink/static.js +8 -9
- package/dist/cli/services/upgrade.js +9 -10
- package/dist/cli/services/upgrade.test.js +11 -12
- package/dist/{custom-oclif-loader-RINU7HR3.js → custom-oclif-loader-AAJZ7WBW.js} +8 -9
- package/dist/{del-E4LJOSMR.js → del-63DSU6FP.js} +7 -7
- package/dist/{devtools-D47L6HIC.js → devtools-4MXU7BNJ.js} +2 -2
- package/dist/{devtools-2SG3BFWJ.js → devtools-BAOTGU3O.js} +2 -2
- package/dist/{error-handler-CWNDOJLB.js → error-handler-GSQRFK57.js} +12 -14
- package/dist/{estree-PY6WKTNG.js → estree-U57GTUKI.js} +14 -35
- package/dist/{flow-YN54TSCB.js → flow-CBPGBIW5.js} +2 -4
- package/dist/{glimmer-RMPUUUDS.js → glimmer-VWCK7UCR.js} +2 -6
- package/dist/{graphql-PPLVYWBL.js → graphql-2HHXB4VZ.js} +3 -5
- package/dist/hooks/postrun.js +13 -13
- package/dist/hooks/prerun.js +14 -14
- package/dist/{html-3U6QZZZ4.js → html-ST4I6M3K.js} +4 -6
- package/dist/index.js +143537 -8573
- package/dist/{lib-XGN4IWQ3.js → lib-HAW436ZI.js} +3 -4
- package/dist/{local-FQVEYJ4K.js → local-GOP2BHNI.js} +10 -11
- package/dist/{markdown-RHRQTUMC.js → markdown-NVTT3U3H.js} +4 -13
- package/dist/{meriyah-7MIMHTWQ.js → meriyah-H6RUUN2F.js} +2 -9
- package/dist/{morph-37GC7LQM.js → morph-7WAMUK6I.js} +68 -143
- package/dist/{multipart-parser-IYYNISJK.js → multipart-parser-WKKMXACL.js} +2 -2
- package/dist/{node-package-manager-XIE2HZEQ.js → node-package-manager-W4R4DUTE.js} +9 -10
- package/dist/{npa-E675GQOI.js → npa-GRSJKUWS.js} +5 -7
- package/dist/{postcss-MSOPGY7M.js → postcss-LKRKUSYR.js} +4 -6
- package/dist/prettier-5ODD6NHV.js +36 -0
- package/dist/{source-map-UFUVQCYE.js → source-map-KSW2YKNC.js} +2 -2
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/{ui-UAEFJEFY.js → ui-VRLRLHWH.js} +8 -9
- package/dist/{workerd-EPURL4IC.js → workerd-AO3T6IIJ.js} +19 -22
- package/dist/{yaml-6GALFXQY.js → yaml-54MHMX7H.js} +6 -9
- package/oclif.manifest.json +128 -9
- package/package.json +8 -8
- package/dist/chunk-DOZD5WAI.js +0 -153039
- package/dist/chunk-EZQWZ57B.js +0 -53
- package/dist/chunk-W65CJE3X.js +0 -2238
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Await,
|
|
3
|
-
useLoaderData,
|
|
4
|
-
Link,
|
|
5
|
-
} from 'react-router';
|
|
1
|
+
import {Await, useLoaderData, Link} from 'react-router';
|
|
6
2
|
import type {Route} from './+types/_index';
|
|
7
3
|
import {Suspense} from 'react';
|
|
8
4
|
import {Image} from '@shopify/hydrogen';
|
|
@@ -11,6 +7,7 @@ import type {
|
|
|
11
7
|
RecommendedProductsQuery,
|
|
12
8
|
} from 'storefrontapi.generated';
|
|
13
9
|
import {ProductItem} from '~/components/ProductItem';
|
|
10
|
+
import {MockShopNotice} from '~/components/MockShopNotice';
|
|
14
11
|
|
|
15
12
|
export const meta: Route.MetaFunction = () => {
|
|
16
13
|
return [{title: 'Hydrogen | Home'}];
|
|
@@ -37,6 +34,7 @@ async function loadCriticalData({context}: Route.LoaderArgs) {
|
|
|
37
34
|
]);
|
|
38
35
|
|
|
39
36
|
return {
|
|
37
|
+
isShopLinked: Boolean(context.env.PUBLIC_STORE_DOMAIN),
|
|
40
38
|
featuredCollection: collections.nodes[0],
|
|
41
39
|
};
|
|
42
40
|
}
|
|
@@ -64,6 +62,7 @@ export default function Homepage() {
|
|
|
64
62
|
const data = useLoaderData<typeof loader>();
|
|
65
63
|
return (
|
|
66
64
|
<div className="home">
|
|
65
|
+
{data.isShopLinked ? null : <MockShopNotice />}
|
|
67
66
|
<FeaturedCollection collection={data.featuredCollection} />
|
|
68
67
|
<RecommendedProducts products={data.recommendedProducts} />
|
|
69
68
|
</div>
|
|
@@ -264,23 +264,23 @@ export default function Addresses() {
|
|
|
264
264
|
<div className="account-addresses">
|
|
265
265
|
<h2>Addresses</h2>
|
|
266
266
|
<br />
|
|
267
|
-
|
|
268
|
-
<p>You have no addresses saved.</p>
|
|
269
|
-
) : (
|
|
267
|
+
<div>
|
|
270
268
|
<div>
|
|
271
|
-
<
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
269
|
+
<legend>Create address</legend>
|
|
270
|
+
<NewAddressForm key={addresses.nodes.length} />
|
|
271
|
+
</div>
|
|
272
|
+
<br />
|
|
273
|
+
<hr />
|
|
274
|
+
<br />
|
|
275
|
+
{!addresses.nodes.length ? (
|
|
276
|
+
<p>You have no addresses saved.</p>
|
|
277
|
+
) : (
|
|
278
278
|
<ExistingAddresses
|
|
279
279
|
addresses={addresses}
|
|
280
280
|
defaultAddress={defaultAddress}
|
|
281
281
|
/>
|
|
282
|
-
|
|
283
|
-
|
|
282
|
+
)}
|
|
283
|
+
</div>
|
|
284
284
|
</div>
|
|
285
285
|
);
|
|
286
286
|
}
|
|
@@ -14,14 +14,11 @@ export function shouldRevalidate() {
|
|
|
14
14
|
|
|
15
15
|
export async function loader({context}: Route.LoaderArgs) {
|
|
16
16
|
const {customerAccount} = context;
|
|
17
|
-
const {data, errors} = await customerAccount.query(
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
variables: {
|
|
21
|
-
language: customerAccount.i18n.language,
|
|
22
|
-
},
|
|
17
|
+
const {data, errors} = await customerAccount.query(CUSTOMER_DETAILS_QUERY, {
|
|
18
|
+
variables: {
|
|
19
|
+
language: customerAccount.i18n.language,
|
|
23
20
|
},
|
|
24
|
-
);
|
|
21
|
+
});
|
|
25
22
|
|
|
26
23
|
if (errors?.length || !data?.customer) {
|
|
27
24
|
throw new Error('Customer not found');
|
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
import type {Route} from './+types/account_.login';
|
|
2
2
|
|
|
3
3
|
export async function loader({request, context}: Route.LoaderArgs) {
|
|
4
|
+
const url = new URL(request.url);
|
|
5
|
+
const acrValues = url.searchParams.get('acr_values') || undefined;
|
|
6
|
+
const loginHint = url.searchParams.get('login_hint') || undefined;
|
|
7
|
+
const loginHintMode = url.searchParams.get('login_hint_mode') || undefined;
|
|
8
|
+
const locale = url.searchParams.get('locale') || undefined;
|
|
9
|
+
|
|
4
10
|
return context.customerAccount.login({
|
|
5
11
|
countryCode: context.storefront.i18n.country,
|
|
12
|
+
acrValues,
|
|
13
|
+
loginHint,
|
|
14
|
+
loginHintMode,
|
|
15
|
+
locale,
|
|
6
16
|
});
|
|
7
17
|
}
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Link,
|
|
3
|
-
useLoaderData,
|
|
4
|
-
} from 'react-router';
|
|
1
|
+
import {Link, useLoaderData} from 'react-router';
|
|
5
2
|
import type {Route} from './+types/blogs.$blogHandle._index';
|
|
6
3
|
import {Image, getPaginationVariables} from '@shopify/hydrogen';
|
|
7
4
|
import type {ArticleItemFragment} from 'storefrontapi.generated';
|
|
@@ -26,11 +23,7 @@ export async function loader(args: Route.LoaderArgs) {
|
|
|
26
23
|
* Load data necessary for rendering content above the fold. This is the critical data
|
|
27
24
|
* needed to render the page. If it's unavailable, the whole page should 400 or 500 error.
|
|
28
25
|
*/
|
|
29
|
-
async function loadCriticalData({
|
|
30
|
-
context,
|
|
31
|
-
request,
|
|
32
|
-
params,
|
|
33
|
-
}: Route.LoaderArgs) {
|
|
26
|
+
async function loadCriticalData({context, request, params}: Route.LoaderArgs) {
|
|
34
27
|
const paginationVariables = getPaginationVariables(request, {
|
|
35
28
|
pageBy: 4,
|
|
36
29
|
});
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Link,
|
|
3
|
-
useLoaderData,
|
|
4
|
-
} from 'react-router';
|
|
1
|
+
import {Link, useLoaderData} from 'react-router';
|
|
5
2
|
import type {Route} from './+types/blogs._index';
|
|
6
3
|
import {getPaginationVariables} from '@shopify/hydrogen';
|
|
7
4
|
import {PaginatedResourceSection} from '~/components/PaginatedResourceSection';
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
useLoaderData,
|
|
3
|
-
data,
|
|
4
|
-
type HeadersFunction,
|
|
5
|
-
} from 'react-router';
|
|
1
|
+
import {useLoaderData, data, type HeadersFunction} from 'react-router';
|
|
6
2
|
import type {Route} from './+types/cart';
|
|
7
3
|
import type {CartQueryDataReturn} from '@shopify/hydrogen';
|
|
8
4
|
import {CartForm} from '@shopify/hydrogen';
|
|
@@ -52,18 +48,14 @@ export async function action({request, context}: Route.ActionArgs) {
|
|
|
52
48
|
result = await cart.updateDiscountCodes(discountCodes);
|
|
53
49
|
break;
|
|
54
50
|
}
|
|
55
|
-
case CartForm.ACTIONS.
|
|
51
|
+
case CartForm.ACTIONS.GiftCardCodesAdd: {
|
|
56
52
|
const formGiftCardCode = inputs.giftCardCode;
|
|
57
53
|
|
|
58
|
-
// User inputted gift card code
|
|
59
54
|
const giftCardCodes = (
|
|
60
55
|
formGiftCardCode ? [formGiftCardCode] : []
|
|
61
56
|
) as string[];
|
|
62
57
|
|
|
63
|
-
|
|
64
|
-
giftCardCodes.push(...inputs.giftCardCodes);
|
|
65
|
-
|
|
66
|
-
result = await cart.updateGiftCardCodes(giftCardCodes);
|
|
58
|
+
result = await cart.addGiftCardCodes(giftCardCodes);
|
|
67
59
|
break;
|
|
68
60
|
}
|
|
69
61
|
case CartForm.ACTIONS.GiftCardCodesRemove: {
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import type {Route} from './+types/collections.all';
|
|
2
|
-
import {
|
|
3
|
-
useLoaderData,
|
|
4
|
-
} from 'react-router';
|
|
2
|
+
import {useLoaderData} from 'react-router';
|
|
5
3
|
import {getPaginationVariables, Image, Money} from '@shopify/hydrogen';
|
|
6
4
|
import {PaginatedResourceSection} from '~/components/PaginatedResourceSection';
|
|
7
5
|
import {ProductItem} from '~/components/ProductItem';
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
useLoaderData,
|
|
3
|
-
} from 'react-router';
|
|
1
|
+
import {useLoaderData} from 'react-router';
|
|
4
2
|
import type {Route} from './+types/pages.$handle';
|
|
5
3
|
import {redirectIfHandleIsLocalized} from '~/lib/redirect';
|
|
6
4
|
|
|
@@ -22,11 +20,7 @@ export async function loader(args: Route.LoaderArgs) {
|
|
|
22
20
|
* Load data necessary for rendering content above the fold. This is the critical data
|
|
23
21
|
* needed to render the page. If it's unavailable, the whole page should 400 or 500 error.
|
|
24
22
|
*/
|
|
25
|
-
async function loadCriticalData({
|
|
26
|
-
context,
|
|
27
|
-
request,
|
|
28
|
-
params,
|
|
29
|
-
}: Route.LoaderArgs) {
|
|
23
|
+
async function loadCriticalData({context, request, params}: Route.LoaderArgs) {
|
|
30
24
|
if (!params.handle) {
|
|
31
25
|
throw new Error('Missing page handle');
|
|
32
26
|
}
|
|
@@ -4,7 +4,7 @@ import type {PoliciesQuery, PolicyItemFragment} from 'storefrontapi.generated';
|
|
|
4
4
|
|
|
5
5
|
export async function loader({context}: Route.LoaderArgs) {
|
|
6
6
|
const data: PoliciesQuery = await context.storefront.query(POLICIES_QUERY);
|
|
7
|
-
|
|
7
|
+
|
|
8
8
|
const shopPolicies = data.shop;
|
|
9
9
|
const policies: PolicyItemFragment[] = [
|
|
10
10
|
shopPolicies?.privacyPolicy,
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
redirect,
|
|
3
|
-
useLoaderData,
|
|
4
|
-
} from 'react-router';
|
|
1
|
+
import {redirect, useLoaderData} from 'react-router';
|
|
5
2
|
import type {Route} from './+types/products.$handle';
|
|
6
3
|
import {
|
|
7
4
|
getSelectedProductOptions,
|
|
@@ -40,11 +37,7 @@ export async function loader(args: Route.LoaderArgs) {
|
|
|
40
37
|
* Load data necessary for rendering content above the fold. This is the critical data
|
|
41
38
|
* needed to render the page. If it's unavailable, the whole page should 400 or 500 error.
|
|
42
39
|
*/
|
|
43
|
-
async function loadCriticalData({
|
|
44
|
-
context,
|
|
45
|
-
params,
|
|
46
|
-
request,
|
|
47
|
-
}: Route.LoaderArgs) {
|
|
40
|
+
async function loadCriticalData({context, params, request}: Route.LoaderArgs) {
|
|
48
41
|
const {handle} = params;
|
|
49
42
|
const {storefront} = context;
|
|
50
43
|
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
useLoaderData,
|
|
3
|
-
} from 'react-router';
|
|
1
|
+
import {useLoaderData} from 'react-router';
|
|
4
2
|
import type {Route} from './+types/search';
|
|
5
3
|
import {getPaginationVariables, Analytics} from '@shopify/hydrogen';
|
|
6
4
|
import {SearchForm} from '~/components/SearchForm';
|
|
@@ -10,7 +8,10 @@ import {
|
|
|
10
8
|
type PredictiveSearchReturn,
|
|
11
9
|
getEmptyPredictiveSearchResult,
|
|
12
10
|
} from '~/lib/search';
|
|
13
|
-
import type {
|
|
11
|
+
import type {
|
|
12
|
+
RegularSearchQuery,
|
|
13
|
+
PredictiveSearchQuery,
|
|
14
|
+
} from 'storefrontapi.generated';
|
|
14
15
|
|
|
15
16
|
export const meta: Route.MetaFunction = () => {
|
|
16
17
|
return [{title: `Hydrogen | Search`}];
|
|
@@ -225,9 +226,13 @@ async function regularSearch({
|
|
|
225
226
|
const term = String(url.searchParams.get('q') || '');
|
|
226
227
|
|
|
227
228
|
// Search articles, pages, and products for the `q` term
|
|
228
|
-
const {
|
|
229
|
-
|
|
230
|
-
|
|
229
|
+
const {
|
|
230
|
+
errors,
|
|
231
|
+
...items
|
|
232
|
+
}: {errors?: Array<{message: string}>} & RegularSearchQuery =
|
|
233
|
+
await storefront.query(SEARCH_QUERY, {
|
|
234
|
+
variables: {...variables, term},
|
|
235
|
+
});
|
|
231
236
|
|
|
232
237
|
if (!items) {
|
|
233
238
|
throw new Error('No search data returned from Shopify API');
|
|
@@ -389,17 +394,18 @@ async function predictiveSearch({
|
|
|
389
394
|
if (!term) return {type, term, result: getEmptyPredictiveSearchResult()};
|
|
390
395
|
|
|
391
396
|
// Predictively search articles, collections, pages, products, and queries (suggestions)
|
|
392
|
-
const {
|
|
393
|
-
|
|
394
|
-
|
|
397
|
+
const {
|
|
398
|
+
predictiveSearch: items,
|
|
399
|
+
errors,
|
|
400
|
+
}: PredictiveSearchQuery & {errors?: Array<{message: string}>} =
|
|
401
|
+
await storefront.query(PREDICTIVE_SEARCH_QUERY, {
|
|
395
402
|
variables: {
|
|
396
403
|
// customize search options as needed
|
|
397
404
|
limit,
|
|
398
405
|
limitScope: 'EACH',
|
|
399
406
|
term,
|
|
400
407
|
},
|
|
401
|
-
}
|
|
402
|
-
);
|
|
408
|
+
});
|
|
403
409
|
|
|
404
410
|
if (errors) {
|
|
405
411
|
throw new Error(
|
|
@@ -22,6 +22,57 @@ img {
|
|
|
22
22
|
cursor: pointer;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
/*
|
|
26
|
+
* --------------------------------------------------
|
|
27
|
+
* components/MockShopNotice
|
|
28
|
+
* --------------------------------------------------
|
|
29
|
+
*/
|
|
30
|
+
.mock-shop-notice {
|
|
31
|
+
background: var(--color-light);
|
|
32
|
+
border: 1px solid var(--color-dark);
|
|
33
|
+
border-left-width: 0.5rem;
|
|
34
|
+
margin: 1rem 0;
|
|
35
|
+
padding: 0;
|
|
36
|
+
|
|
37
|
+
.inner {
|
|
38
|
+
padding: 0.875rem 1rem;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
h2 {
|
|
42
|
+
font-size: 1.6rem;
|
|
43
|
+
font-weight: 700;
|
|
44
|
+
line-height: 1.4;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
p {
|
|
48
|
+
font-size: 1rem;
|
|
49
|
+
line-height: 1.4;
|
|
50
|
+
margin-bottom: 0.5rem;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
footer {
|
|
54
|
+
background: rgba(0, 0, 0, 0.06);
|
|
55
|
+
padding: 0.5rem 1rem;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.small {
|
|
59
|
+
font-size: 0.875rem;
|
|
60
|
+
line-height: 1.4;
|
|
61
|
+
margin-bottom: 0.5rem;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
code {
|
|
65
|
+
background: rgba(0, 0, 0, 0.06);
|
|
66
|
+
border-radius: 0.25rem;
|
|
67
|
+
padding: 0.1em 0.3em;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
a {
|
|
71
|
+
text-decoration: underline;
|
|
72
|
+
text-underline-offset: 6px;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
25
76
|
/*
|
|
26
77
|
* --------------------------------------------------
|
|
27
78
|
* components/Aside
|
|
@@ -90,6 +141,18 @@ aside li {
|
|
|
90
141
|
margin-bottom: 0.125rem;
|
|
91
142
|
}
|
|
92
143
|
|
|
144
|
+
.sr-only {
|
|
145
|
+
position: absolute;
|
|
146
|
+
width: 1px;
|
|
147
|
+
height: 1px;
|
|
148
|
+
padding: 0;
|
|
149
|
+
margin: -1px;
|
|
150
|
+
overflow: hidden;
|
|
151
|
+
clip-path: inset(50%);
|
|
152
|
+
white-space: nowrap;
|
|
153
|
+
border-width: 0;
|
|
154
|
+
}
|
|
155
|
+
|
|
93
156
|
.overlay {
|
|
94
157
|
background: rgba(0, 0, 0, 0.2);
|
|
95
158
|
bottom: 0;
|
|
@@ -250,10 +313,13 @@ button.reset:hover:not(:has(> *)) {
|
|
|
250
313
|
}
|
|
251
314
|
|
|
252
315
|
.cart-line {
|
|
253
|
-
display: flex;
|
|
254
316
|
padding: 0.75rem 0;
|
|
255
317
|
}
|
|
256
318
|
|
|
319
|
+
.cart-line-inner {
|
|
320
|
+
display: flex;
|
|
321
|
+
}
|
|
322
|
+
|
|
257
323
|
.cart-line img {
|
|
258
324
|
height: 100%;
|
|
259
325
|
display: block;
|
|
@@ -277,6 +343,11 @@ button.reset:hover:not(:has(> *)) {
|
|
|
277
343
|
display: flex;
|
|
278
344
|
}
|
|
279
345
|
|
|
346
|
+
/* Child line components (warranties, gift wrapping, etc.) */
|
|
347
|
+
.cart-line-children {
|
|
348
|
+
padding-left: 2rem;
|
|
349
|
+
}
|
|
350
|
+
|
|
280
351
|
.cart-discount {
|
|
281
352
|
align-items: center;
|
|
282
353
|
display: flex;
|
|
@@ -15,7 +15,7 @@ This integration uses the storefront API (SFAPI) [predictiveSearch](https://shop
|
|
|
15
15
|
|
|
16
16
|
| File | Description |
|
|
17
17
|
| ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
18
|
-
| [`app/components/SearchFormPredictive.tsx`](../../app/components/SearchFormPredictive.tsx) | A fully customizable form component configured to make form `GET` requests to the `/search` route.
|
|
18
|
+
| [`app/components/SearchFormPredictive.tsx`](../../app/components/SearchFormPredictive.tsx) | A fully customizable form component configured to make form `GET` requests to the `/search` route. |
|
|
19
19
|
| [`app/components/SearchResultsPredictive.tsx`](../../app/components/SearchResultsPredictive.tsx) | A fully customizable search results wrapper, that provides compound components to render `articles`, `pages`, `products`, `collections` and `queries`. |
|
|
20
20
|
|
|
21
21
|
## Instructions
|
|
@@ -217,10 +217,10 @@ export async function loader({request, context}: LoaderFunctionArgs) {
|
|
|
217
217
|
const isPredictive = url.searchParams.has('predictive');
|
|
218
218
|
|
|
219
219
|
if (!isPredictive) {
|
|
220
|
-
return {}
|
|
220
|
+
return {};
|
|
221
221
|
}
|
|
222
222
|
|
|
223
|
-
const searchPromise = predictiveSearch({request, context})
|
|
223
|
+
const searchPromise = predictiveSearch({request, context});
|
|
224
224
|
|
|
225
225
|
searchPromise.catch((error: Error) => {
|
|
226
226
|
console.error(error);
|
|
@@ -212,7 +212,7 @@ export async function loader({request, context}: LoaderFunctionArgs) {
|
|
|
212
212
|
const isRegular = !url.searchParams.has('predictive');
|
|
213
213
|
|
|
214
214
|
if (!isRegular) {
|
|
215
|
-
return {}
|
|
215
|
+
return {};
|
|
216
216
|
}
|
|
217
217
|
|
|
218
218
|
const searchPromise = regularSearch({request, context});
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "skeleton",
|
|
3
3
|
"private": true,
|
|
4
4
|
"sideEffects": false,
|
|
5
|
-
"version": "
|
|
5
|
+
"version": "2026.1.1",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"build": "shopify hydrogen build --codegen",
|
|
@@ -14,31 +14,31 @@
|
|
|
14
14
|
},
|
|
15
15
|
"prettier": "@shopify/prettier-config",
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@shopify/hydrogen": "
|
|
17
|
+
"@shopify/hydrogen": "*2026.1.1",
|
|
18
18
|
"graphql": "^16.10.0",
|
|
19
19
|
"graphql-tag": "^2.12.6",
|
|
20
20
|
"isbot": "^5.1.22",
|
|
21
|
-
"react": "18.3.1",
|
|
22
|
-
"react-dom": "18.3.1",
|
|
23
|
-
"react-router": "7.
|
|
24
|
-
"react-router-dom": "7.
|
|
21
|
+
"react": "^18.3.1",
|
|
22
|
+
"react-dom": "^18.3.1",
|
|
23
|
+
"react-router": "7.12.0",
|
|
24
|
+
"react-router-dom": "7.12.0"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@eslint/compat": "^1.2.5",
|
|
28
28
|
"@eslint/eslintrc": "^3.2.0",
|
|
29
29
|
"@eslint/js": "^9.18.0",
|
|
30
30
|
"@graphql-codegen/cli": "5.0.2",
|
|
31
|
-
"@react-router/dev": "7.
|
|
32
|
-
"@react-router/fs-routes": "7.
|
|
31
|
+
"@react-router/dev": "7.12.0",
|
|
32
|
+
"@react-router/fs-routes": "7.12.0",
|
|
33
33
|
"@shopify/cli": "3.85.4",
|
|
34
|
-
"@shopify/hydrogen-codegen": "
|
|
35
|
-
"@shopify/mini-oxygen": "
|
|
34
|
+
"@shopify/hydrogen-codegen": "0.3.3",
|
|
35
|
+
"@shopify/mini-oxygen": "4.0.1",
|
|
36
36
|
"@shopify/oxygen-workers-types": "^4.1.6",
|
|
37
37
|
"@shopify/prettier-config": "^1.1.2",
|
|
38
38
|
"@total-typescript/ts-reset": "^0.6.1",
|
|
39
39
|
"@types/eslint": "^9.6.1",
|
|
40
|
-
"@types/react": "^18.
|
|
41
|
-
"@types/react-dom": "^18.
|
|
40
|
+
"@types/react": "^18.3.28",
|
|
41
|
+
"@types/react-dom": "^18.3.7",
|
|
42
42
|
"@typescript-eslint/eslint-plugin": "^8.21.0",
|
|
43
43
|
"@typescript-eslint/parser": "^8.21.0",
|
|
44
44
|
"eslint": "^9.18.0",
|
|
@@ -51,12 +51,13 @@
|
|
|
51
51
|
"eslint-plugin-react": "^7.37.4",
|
|
52
52
|
"eslint-plugin-react-hooks": "^5.1.0",
|
|
53
53
|
"globals": "^15.14.0",
|
|
54
|
+
"graphql-config": "^5.0.3",
|
|
54
55
|
"prettier": "^3.4.2",
|
|
55
56
|
"typescript": "^5.9.2",
|
|
56
57
|
"vite": "^6.2.4",
|
|
57
58
|
"vite-tsconfig-paths": "^4.3.1"
|
|
58
59
|
},
|
|
59
60
|
"engines": {
|
|
60
|
-
"node": "
|
|
61
|
+
"node": "^22 || ^24"
|
|
61
62
|
}
|
|
62
63
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
import {storefrontRedirect} from '@shopify/hydrogen';
|
|
3
|
-
import {createRequestHandler} from '@shopify/hydrogen/oxygen';
|
|
1
|
+
import * as serverBuild from 'virtual:react-router/server-build';
|
|
2
|
+
import {createRequestHandler, storefrontRedirect} from '@shopify/hydrogen';
|
|
4
3
|
import {createHydrogenRouterContext} from '~/lib/context';
|
|
5
4
|
|
|
6
5
|
/**
|
|
@@ -20,12 +19,11 @@ export default {
|
|
|
20
19
|
);
|
|
21
20
|
|
|
22
21
|
/**
|
|
23
|
-
* Create a
|
|
24
|
-
*
|
|
22
|
+
* Create a Hydrogen request handler that internally
|
|
23
|
+
* delegates to React Router for routing and rendering.
|
|
25
24
|
*/
|
|
26
25
|
const handleRequest = createRequestHandler({
|
|
27
|
-
|
|
28
|
-
build: await import('virtual:react-router/server-build'),
|
|
26
|
+
build: serverBuild,
|
|
29
27
|
mode: process.env.NODE_ENV,
|
|
30
28
|
getLoadContext: () => hydrogenContext,
|
|
31
29
|
});
|
|
@@ -36,6 +36,9 @@ export type CartLineFragment = Pick<
|
|
|
36
36
|
Pick<StorefrontAPI.SelectedOption, 'name' | 'value'>
|
|
37
37
|
>;
|
|
38
38
|
};
|
|
39
|
+
parentRelationship?: StorefrontAPI.Maybe<{
|
|
40
|
+
parent: Pick<StorefrontAPI.CartLine, 'id'>;
|
|
41
|
+
}>;
|
|
39
42
|
};
|
|
40
43
|
|
|
41
44
|
export type CartLineComponentFragment = Pick<
|
|
@@ -66,6 +69,46 @@ export type CartLineComponentFragment = Pick<
|
|
|
66
69
|
Pick<StorefrontAPI.SelectedOption, 'name' | 'value'>
|
|
67
70
|
>;
|
|
68
71
|
};
|
|
72
|
+
lineComponents: Array<
|
|
73
|
+
Pick<StorefrontAPI.CartLine, 'id' | 'quantity'> & {
|
|
74
|
+
attributes: Array<Pick<StorefrontAPI.Attribute, 'key' | 'value'>>;
|
|
75
|
+
cost: {
|
|
76
|
+
totalAmount: Pick<StorefrontAPI.MoneyV2, 'currencyCode' | 'amount'>;
|
|
77
|
+
amountPerQuantity: Pick<
|
|
78
|
+
StorefrontAPI.MoneyV2,
|
|
79
|
+
'currencyCode' | 'amount'
|
|
80
|
+
>;
|
|
81
|
+
compareAtAmountPerQuantity?: StorefrontAPI.Maybe<
|
|
82
|
+
Pick<StorefrontAPI.MoneyV2, 'currencyCode' | 'amount'>
|
|
83
|
+
>;
|
|
84
|
+
};
|
|
85
|
+
merchandise: Pick<
|
|
86
|
+
StorefrontAPI.ProductVariant,
|
|
87
|
+
'id' | 'availableForSale' | 'requiresShipping' | 'title'
|
|
88
|
+
> & {
|
|
89
|
+
compareAtPrice?: StorefrontAPI.Maybe<
|
|
90
|
+
Pick<StorefrontAPI.MoneyV2, 'currencyCode' | 'amount'>
|
|
91
|
+
>;
|
|
92
|
+
price: Pick<StorefrontAPI.MoneyV2, 'currencyCode' | 'amount'>;
|
|
93
|
+
image?: StorefrontAPI.Maybe<
|
|
94
|
+
Pick<
|
|
95
|
+
StorefrontAPI.Image,
|
|
96
|
+
'id' | 'url' | 'altText' | 'width' | 'height'
|
|
97
|
+
>
|
|
98
|
+
>;
|
|
99
|
+
product: Pick<
|
|
100
|
+
StorefrontAPI.Product,
|
|
101
|
+
'handle' | 'title' | 'id' | 'vendor'
|
|
102
|
+
>;
|
|
103
|
+
selectedOptions: Array<
|
|
104
|
+
Pick<StorefrontAPI.SelectedOption, 'name' | 'value'>
|
|
105
|
+
>;
|
|
106
|
+
};
|
|
107
|
+
parentRelationship?: StorefrontAPI.Maybe<{
|
|
108
|
+
parent: Pick<StorefrontAPI.CartLine, 'id'>;
|
|
109
|
+
}>;
|
|
110
|
+
}
|
|
111
|
+
>;
|
|
69
112
|
};
|
|
70
113
|
|
|
71
114
|
export type CartApiQueryFragment = Pick<
|
|
@@ -124,6 +167,9 @@ export type CartApiQueryFragment = Pick<
|
|
|
124
167
|
Pick<StorefrontAPI.SelectedOption, 'name' | 'value'>
|
|
125
168
|
>;
|
|
126
169
|
};
|
|
170
|
+
parentRelationship?: StorefrontAPI.Maybe<{
|
|
171
|
+
parent: Pick<StorefrontAPI.CartLine, 'id'>;
|
|
172
|
+
}>;
|
|
127
173
|
})
|
|
128
174
|
| (Pick<StorefrontAPI.ComponentizableCartLine, 'id' | 'quantity'> & {
|
|
129
175
|
attributes: Array<Pick<StorefrontAPI.Attribute, 'key' | 'value'>>;
|
|
@@ -159,6 +205,49 @@ export type CartApiQueryFragment = Pick<
|
|
|
159
205
|
Pick<StorefrontAPI.SelectedOption, 'name' | 'value'>
|
|
160
206
|
>;
|
|
161
207
|
};
|
|
208
|
+
lineComponents: Array<
|
|
209
|
+
Pick<StorefrontAPI.CartLine, 'id' | 'quantity'> & {
|
|
210
|
+
attributes: Array<Pick<StorefrontAPI.Attribute, 'key' | 'value'>>;
|
|
211
|
+
cost: {
|
|
212
|
+
totalAmount: Pick<
|
|
213
|
+
StorefrontAPI.MoneyV2,
|
|
214
|
+
'currencyCode' | 'amount'
|
|
215
|
+
>;
|
|
216
|
+
amountPerQuantity: Pick<
|
|
217
|
+
StorefrontAPI.MoneyV2,
|
|
218
|
+
'currencyCode' | 'amount'
|
|
219
|
+
>;
|
|
220
|
+
compareAtAmountPerQuantity?: StorefrontAPI.Maybe<
|
|
221
|
+
Pick<StorefrontAPI.MoneyV2, 'currencyCode' | 'amount'>
|
|
222
|
+
>;
|
|
223
|
+
};
|
|
224
|
+
merchandise: Pick<
|
|
225
|
+
StorefrontAPI.ProductVariant,
|
|
226
|
+
'id' | 'availableForSale' | 'requiresShipping' | 'title'
|
|
227
|
+
> & {
|
|
228
|
+
compareAtPrice?: StorefrontAPI.Maybe<
|
|
229
|
+
Pick<StorefrontAPI.MoneyV2, 'currencyCode' | 'amount'>
|
|
230
|
+
>;
|
|
231
|
+
price: Pick<StorefrontAPI.MoneyV2, 'currencyCode' | 'amount'>;
|
|
232
|
+
image?: StorefrontAPI.Maybe<
|
|
233
|
+
Pick<
|
|
234
|
+
StorefrontAPI.Image,
|
|
235
|
+
'id' | 'url' | 'altText' | 'width' | 'height'
|
|
236
|
+
>
|
|
237
|
+
>;
|
|
238
|
+
product: Pick<
|
|
239
|
+
StorefrontAPI.Product,
|
|
240
|
+
'handle' | 'title' | 'id' | 'vendor'
|
|
241
|
+
>;
|
|
242
|
+
selectedOptions: Array<
|
|
243
|
+
Pick<StorefrontAPI.SelectedOption, 'name' | 'value'>
|
|
244
|
+
>;
|
|
245
|
+
};
|
|
246
|
+
parentRelationship?: StorefrontAPI.Maybe<{
|
|
247
|
+
parent: Pick<StorefrontAPI.CartLine, 'id'>;
|
|
248
|
+
}>;
|
|
249
|
+
}
|
|
250
|
+
>;
|
|
162
251
|
})
|
|
163
252
|
>;
|
|
164
253
|
};
|