@shopify/cli-hydrogen 5.5.0 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/dist/commands/hydrogen/build.js +2 -6
  2. package/dist/commands/hydrogen/{codegen-unstable.js → codegen.js} +2 -0
  3. package/dist/commands/hydrogen/deploy.js +1 -0
  4. package/dist/commands/hydrogen/deploy.test.js +1 -0
  5. package/dist/commands/hydrogen/dev.js +6 -8
  6. package/dist/commands/hydrogen/generate/route.js +5 -1
  7. package/dist/commands/hydrogen/generate/route.test.js +4 -2
  8. package/dist/commands/hydrogen/init.test.js +1 -4
  9. package/dist/commands/hydrogen/setup.js +1 -6
  10. package/dist/generator-templates/starter/CHANGELOG.md +143 -0
  11. package/dist/generator-templates/starter/app/components/Footer.tsx +19 -8
  12. package/dist/generator-templates/starter/app/components/Header.tsx +13 -5
  13. package/dist/generator-templates/starter/app/components/Layout.tsx +14 -4
  14. package/dist/generator-templates/starter/app/root.tsx +14 -27
  15. package/dist/generator-templates/starter/app/routes/$.tsx +2 -2
  16. package/dist/generator-templates/starter/app/routes/[robots.txt].tsx +2 -2
  17. package/dist/generator-templates/starter/app/routes/[sitemap.xml].tsx +5 -2
  18. package/dist/generator-templates/starter/app/routes/_index.tsx +4 -9
  19. package/dist/generator-templates/starter/app/routes/account.$.tsx +2 -2
  20. package/dist/generator-templates/starter/app/routes/account.addresses.tsx +6 -6
  21. package/dist/generator-templates/starter/app/routes/account.orders.$id.tsx +4 -4
  22. package/dist/generator-templates/starter/app/routes/account.orders._index.tsx +4 -4
  23. package/dist/generator-templates/starter/app/routes/account.profile.tsx +6 -6
  24. package/dist/generator-templates/starter/app/routes/account.tsx +2 -2
  25. package/dist/generator-templates/starter/app/routes/account_.activate.$id.$activationToken.tsx +6 -6
  26. package/dist/generator-templates/starter/app/routes/account_.login.tsx +6 -11
  27. package/dist/generator-templates/starter/app/routes/account_.logout.tsx +4 -4
  28. package/dist/generator-templates/starter/app/routes/account_.recover.tsx +4 -4
  29. package/dist/generator-templates/starter/app/routes/account_.register.tsx +4 -4
  30. package/dist/generator-templates/starter/app/routes/account_.reset.$id.$resetToken.tsx +4 -4
  31. package/dist/generator-templates/starter/app/routes/api.predictive-search.tsx +4 -4
  32. package/dist/generator-templates/starter/app/routes/blogs.$blogHandle.$articleHandle.tsx +5 -5
  33. package/dist/generator-templates/starter/app/routes/blogs.$blogHandle._index.tsx +5 -5
  34. package/dist/generator-templates/starter/app/routes/blogs._index.tsx +7 -4
  35. package/dist/generator-templates/starter/app/routes/cart.$lines.tsx +2 -2
  36. package/dist/generator-templates/starter/app/routes/cart.tsx +11 -8
  37. package/dist/generator-templates/starter/app/routes/collections.$handle.tsx +5 -5
  38. package/dist/generator-templates/starter/app/routes/collections._index.tsx +2 -2
  39. package/dist/generator-templates/starter/app/routes/discount.$code.tsx +2 -2
  40. package/dist/generator-templates/starter/app/routes/pages.$handle.tsx +5 -5
  41. package/dist/generator-templates/starter/app/routes/policies.$handle.tsx +5 -5
  42. package/dist/generator-templates/starter/app/routes/policies._index.tsx +2 -2
  43. package/dist/generator-templates/starter/app/routes/products.$handle.tsx +7 -7
  44. package/dist/generator-templates/starter/app/routes/search.tsx +5 -4
  45. package/dist/generator-templates/starter/app/styles/app.css +16 -16
  46. package/dist/generator-templates/starter/package.json +10 -10
  47. package/dist/generator-templates/starter/remix.config.js +0 -8
  48. package/dist/generator-templates/starter/storefrontapi.generated.d.ts +79 -55
  49. package/dist/lib/codegen.js +31 -22
  50. package/dist/lib/flags.js +8 -1
  51. package/dist/lib/onboarding/common.js +2 -14
  52. package/dist/lib/remix-version-check.js +2 -1
  53. package/dist/lib/remix-version-interop.js +1 -39
  54. package/dist/lib/remix-version-interop.test.js +8 -98
  55. package/dist/lib/setups/css/postcss.js +1 -6
  56. package/dist/lib/setups/css/tailwind.js +6 -12
  57. package/dist/lib/setups/routes/generate.js +13 -23
  58. package/dist/lib/setups/routes/generate.test.js +6 -20
  59. package/dist/lib/transpile/morph/typedefs.js +1 -1
  60. package/oclif.manifest.json +29 -16
  61. package/package.json +13 -9
@@ -1,13 +1,13 @@
1
- import {json, redirect, type LoaderArgs} from '@shopify/remix-oxygen';
2
- import {Link, useLoaderData, type V2_MetaFunction} from '@remix-run/react';
1
+ import {json, redirect, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
2
+ import {Link, useLoaderData, type MetaFunction} from '@remix-run/react';
3
3
  import {Money, Image, flattenConnection} from '@shopify/hydrogen';
4
4
  import type {OrderLineItemFullFragment} from 'storefrontapi.generated';
5
5
 
6
- export const meta: V2_MetaFunction<typeof loader> = ({data}) => {
6
+ export const meta: MetaFunction<typeof loader> = ({data}) => {
7
7
  return [{title: `Order ${data?.order?.name}`}];
8
8
  };
9
9
 
10
- export async function loader({params, context}: LoaderArgs) {
10
+ export async function loader({params, context}: LoaderFunctionArgs) {
11
11
  const {session, storefront} = context;
12
12
 
13
13
  if (!params.id) {
@@ -1,16 +1,16 @@
1
- import {Link, useLoaderData, type V2_MetaFunction} from '@remix-run/react';
1
+ import {Link, useLoaderData, type MetaFunction} from '@remix-run/react';
2
2
  import {Money, Pagination, getPaginationVariables} from '@shopify/hydrogen';
3
- import {json, redirect, type LoaderArgs} from '@shopify/remix-oxygen';
3
+ import {json, redirect, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
4
4
  import type {
5
5
  CustomerOrdersFragment,
6
6
  OrderItemFragment,
7
7
  } from 'storefrontapi.generated';
8
8
 
9
- export const meta: V2_MetaFunction = () => {
9
+ export const meta: MetaFunction = () => {
10
10
  return [{title: 'Orders'}];
11
11
  };
12
12
 
13
- export async function loader({request, context}: LoaderArgs) {
13
+ export async function loader({request, context}: LoaderFunctionArgs) {
14
14
  const {session, storefront} = context;
15
15
 
16
16
  const customerAccessToken = await session.get('customerAccessToken');
@@ -3,15 +3,15 @@ import type {CustomerUpdateInput} from '@shopify/hydrogen/storefront-api-types';
3
3
  import {
4
4
  json,
5
5
  redirect,
6
- type ActionArgs,
7
- type LoaderArgs,
6
+ type ActionFunctionArgs,
7
+ type LoaderFunctionArgs,
8
8
  } from '@shopify/remix-oxygen';
9
9
  import {
10
10
  Form,
11
11
  useActionData,
12
12
  useNavigation,
13
13
  useOutletContext,
14
- type V2_MetaFunction,
14
+ type MetaFunction,
15
15
  } from '@remix-run/react';
16
16
 
17
17
  export type ActionResponse = {
@@ -19,11 +19,11 @@ export type ActionResponse = {
19
19
  customer: CustomerFragment | null;
20
20
  };
21
21
 
22
- export const meta: V2_MetaFunction = () => {
22
+ export const meta: MetaFunction = () => {
23
23
  return [{title: 'Profile'}];
24
24
  };
25
25
 
26
- export async function loader({context}: LoaderArgs) {
26
+ export async function loader({context}: LoaderFunctionArgs) {
27
27
  const customerAccessToken = await context.session.get('customerAccessToken');
28
28
  if (!customerAccessToken) {
29
29
  return redirect('/account/login');
@@ -31,7 +31,7 @@ export async function loader({context}: LoaderArgs) {
31
31
  return json({});
32
32
  }
33
33
 
34
- export async function action({request, context}: ActionArgs) {
34
+ export async function action({request, context}: ActionFunctionArgs) {
35
35
  const {session, storefront} = context;
36
36
 
37
37
  if (request.method !== 'PUT') {
@@ -1,12 +1,12 @@
1
1
  import {Form, NavLink, Outlet, useLoaderData} from '@remix-run/react';
2
- import {json, redirect, type LoaderArgs} from '@shopify/remix-oxygen';
2
+ import {json, redirect, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
3
3
  import type {CustomerFragment} from 'storefrontapi.generated';
4
4
 
5
5
  export function shouldRevalidate() {
6
6
  return true;
7
7
  }
8
8
 
9
- export async function loader({request, context}: LoaderArgs) {
9
+ export async function loader({request, context}: LoaderFunctionArgs) {
10
10
  const {session, storefront} = context;
11
11
  const {pathname} = new URL(request.url);
12
12
  const customerAccessToken = await session.get('customerAccessToken');
@@ -1,27 +1,27 @@
1
1
  import {
2
2
  json,
3
3
  redirect,
4
- type ActionArgs,
5
- type LoaderArgs,
4
+ type ActionFunctionArgs,
5
+ type LoaderFunctionArgs,
6
6
  } from '@shopify/remix-oxygen';
7
- import {Form, useActionData, type V2_MetaFunction} from '@remix-run/react';
7
+ import {Form, useActionData, type MetaFunction} from '@remix-run/react';
8
8
 
9
9
  type ActionResponse = {
10
10
  error: string | null;
11
11
  };
12
12
 
13
- export const meta: V2_MetaFunction = () => {
13
+ export const meta: MetaFunction = () => {
14
14
  return [{title: 'Activate Account'}];
15
15
  };
16
16
 
17
- export async function loader({context}: LoaderArgs) {
17
+ export async function loader({context}: LoaderFunctionArgs) {
18
18
  if (await context.session.get('customerAccessToken')) {
19
19
  return redirect('/account');
20
20
  }
21
21
  return json({});
22
22
  }
23
23
 
24
- export async function action({request, context, params}: ActionArgs) {
24
+ export async function action({request, context, params}: ActionFunctionArgs) {
25
25
  const {session, storefront} = context;
26
26
  const {id, activationToken} = params;
27
27
 
@@ -1,32 +1,27 @@
1
1
  import {
2
2
  json,
3
3
  redirect,
4
- type ActionArgs,
5
- type LoaderArgs,
4
+ type ActionFunctionArgs,
5
+ type LoaderFunctionArgs,
6
6
  } from '@shopify/remix-oxygen';
7
- import {
8
- Form,
9
- Link,
10
- useActionData,
11
- type V2_MetaFunction,
12
- } from '@remix-run/react';
7
+ import {Form, Link, useActionData, type MetaFunction} from '@remix-run/react';
13
8
 
14
9
  type ActionResponse = {
15
10
  error: string | null;
16
11
  };
17
12
 
18
- export const meta: V2_MetaFunction = () => {
13
+ export const meta: MetaFunction = () => {
19
14
  return [{title: 'Login'}];
20
15
  };
21
16
 
22
- export async function loader({context}: LoaderArgs) {
17
+ export async function loader({context}: LoaderFunctionArgs) {
23
18
  if (await context.session.get('customerAccessToken')) {
24
19
  return redirect('/account');
25
20
  }
26
21
  return json({});
27
22
  }
28
23
 
29
- export async function action({request, context}: ActionArgs) {
24
+ export async function action({request, context}: ActionFunctionArgs) {
30
25
  const {session, storefront} = context;
31
26
 
32
27
  if (request.method !== 'POST') {
@@ -1,7 +1,7 @@
1
- import {json, redirect, type ActionArgs} from '@shopify/remix-oxygen';
2
- import {type V2_MetaFunction} from '@remix-run/react';
1
+ import {json, redirect, type ActionFunctionArgs} from '@shopify/remix-oxygen';
2
+ import {type MetaFunction} from '@remix-run/react';
3
3
 
4
- export const meta: V2_MetaFunction = () => {
4
+ export const meta: MetaFunction = () => {
5
5
  return [{title: 'Logout'}];
6
6
  };
7
7
 
@@ -9,7 +9,7 @@ export async function loader() {
9
9
  return redirect('/account/login');
10
10
  }
11
11
 
12
- export async function action({request, context}: ActionArgs) {
12
+ export async function action({request, context}: ActionFunctionArgs) {
13
13
  const {session} = context;
14
14
  session.unset('customerAccessToken');
15
15
 
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  json,
3
3
  redirect,
4
- type LoaderArgs,
5
- type ActionArgs,
4
+ type LoaderFunctionArgs,
5
+ type ActionFunctionArgs,
6
6
  } from '@shopify/remix-oxygen';
7
7
  import {Form, Link, useActionData} from '@remix-run/react';
8
8
 
@@ -11,7 +11,7 @@ type ActionResponse = {
11
11
  resetRequested?: boolean;
12
12
  };
13
13
 
14
- export async function loader({context}: LoaderArgs) {
14
+ export async function loader({context}: LoaderFunctionArgs) {
15
15
  const customerAccessToken = await context.session.get('customerAccessToken');
16
16
  if (customerAccessToken) {
17
17
  return redirect('/account');
@@ -20,7 +20,7 @@ export async function loader({context}: LoaderArgs) {
20
20
  return json({});
21
21
  }
22
22
 
23
- export async function action({request, context}: ActionArgs) {
23
+ export async function action({request, context}: ActionFunctionArgs) {
24
24
  const {storefront} = context;
25
25
  const form = await request.formData();
26
26
  const email = form.has('email') ? String(form.get('email')) : null;
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  json,
3
3
  redirect,
4
- type LoaderArgs,
5
- type ActionArgs,
4
+ type ActionFunctionArgs,
5
+ type LoaderFunctionArgs,
6
6
  } from '@shopify/remix-oxygen';
7
7
  import {Form, Link, useActionData} from '@remix-run/react';
8
8
  import type {CustomerCreateMutation} from 'storefrontapi.generated';
@@ -14,7 +14,7 @@ type ActionResponse = {
14
14
  | null;
15
15
  };
16
16
 
17
- export async function loader({context}: LoaderArgs) {
17
+ export async function loader({context}: LoaderFunctionArgs) {
18
18
  const customerAccessToken = await context.session.get('customerAccessToken');
19
19
  if (customerAccessToken) {
20
20
  return redirect('/account');
@@ -23,7 +23,7 @@ export async function loader({context}: LoaderArgs) {
23
23
  return json({});
24
24
  }
25
25
 
26
- export async function action({request, context}: ActionArgs) {
26
+ export async function action({request, context}: ActionFunctionArgs) {
27
27
  if (request.method !== 'POST') {
28
28
  return json({error: 'Method not allowed'}, {status: 405});
29
29
  }
@@ -1,15 +1,15 @@
1
- import {type ActionArgs, json, redirect} from '@shopify/remix-oxygen';
2
- import {Form, useActionData, type V2_MetaFunction} from '@remix-run/react';
1
+ import {type ActionFunctionArgs, json, redirect} from '@shopify/remix-oxygen';
2
+ import {Form, useActionData, type MetaFunction} from '@remix-run/react';
3
3
 
4
4
  type ActionResponse = {
5
5
  error: string | null;
6
6
  };
7
7
 
8
- export const meta: V2_MetaFunction = () => {
8
+ export const meta: MetaFunction = () => {
9
9
  return [{title: 'Reset Password'}];
10
10
  };
11
11
 
12
- export async function action({request, context, params}: ActionArgs) {
12
+ export async function action({request, context, params}: ActionFunctionArgs) {
13
13
  if (request.method !== 'POST') {
14
14
  return json({error: 'Method not allowed'}, {status: 405});
15
15
  }
@@ -1,4 +1,4 @@
1
- import {json, type LoaderArgs} from '@shopify/remix-oxygen';
1
+ import {json, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
2
2
  import type {
3
3
  NormalizedPredictiveSearch,
4
4
  NormalizedPredictiveSearchResults,
@@ -39,7 +39,7 @@ const DEFAULT_SEARCH_TYPES: PredictiveSearchTypes[] = [
39
39
  * Fetches the search results from the predictive search API
40
40
  * requested by the SearchForm component
41
41
  */
42
- export async function action({request, params, context}: LoaderArgs) {
42
+ export async function action({request, params, context}: LoaderFunctionArgs) {
43
43
  if (request.method !== 'POST') {
44
44
  throw new Error('Invalid request method');
45
45
  }
@@ -57,7 +57,7 @@ async function fetchPredictiveSearchResults({
57
57
  params,
58
58
  request,
59
59
  context,
60
- }: Pick<LoaderArgs, 'params' | 'context' | 'request'>) {
60
+ }: Pick<LoaderFunctionArgs, 'params' | 'context' | 'request'>) {
61
61
  const url = new URL(request.url);
62
62
  const searchParams = new URLSearchParams(url.search);
63
63
  let body;
@@ -111,7 +111,7 @@ async function fetchPredictiveSearchResults({
111
111
  */
112
112
  export function normalizePredictiveSearchResults(
113
113
  predictiveSearch: PredictiveSearchQuery['predictiveSearch'],
114
- locale: LoaderArgs['params']['locale'],
114
+ locale: LoaderFunctionArgs['params']['locale'],
115
115
  ): NormalizedPredictiveSearch {
116
116
  let totalResults = 0;
117
117
  if (!predictiveSearch) {
@@ -1,12 +1,12 @@
1
- import {json, type LoaderArgs} from '@shopify/remix-oxygen';
2
- import {useLoaderData, type V2_MetaFunction} from '@remix-run/react';
1
+ import {json, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
2
+ import {useLoaderData, type MetaFunction} from '@remix-run/react';
3
3
  import {Image} from '@shopify/hydrogen';
4
4
 
5
- export const meta: V2_MetaFunction = ({data}) => {
6
- return [{title: `Hydrogen | ${data.article.title} article`}];
5
+ export const meta: MetaFunction<typeof loader> = ({data}) => {
6
+ return [{title: `Hydrogen | ${data?.article.title ?? ''} article`}];
7
7
  };
8
8
 
9
- export async function loader({params, context}: LoaderArgs) {
9
+ export async function loader({params, context}: LoaderFunctionArgs) {
10
10
  const {blogHandle, articleHandle} = params;
11
11
 
12
12
  if (!articleHandle || !blogHandle) {
@@ -1,17 +1,17 @@
1
- import {json, type LoaderArgs} from '@shopify/remix-oxygen';
2
- import {Link, useLoaderData, type V2_MetaFunction} from '@remix-run/react';
1
+ import {json, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
2
+ import {Link, useLoaderData, type MetaFunction} from '@remix-run/react';
3
3
  import {Image, Pagination, getPaginationVariables} from '@shopify/hydrogen';
4
4
  import type {ArticleItemFragment} from 'storefrontapi.generated';
5
5
 
6
- export const meta: V2_MetaFunction = ({data}) => {
7
- return [{title: `Hydrogen | ${data.blog.title} blog`}];
6
+ export const meta: MetaFunction<typeof loader> = ({data}) => {
7
+ return [{title: `Hydrogen | ${data?.blog.title ?? ''} blog`}];
8
8
  };
9
9
 
10
10
  export const loader = async ({
11
11
  request,
12
12
  params,
13
13
  context: {storefront},
14
- }: LoaderArgs) => {
14
+ }: LoaderFunctionArgs) => {
15
15
  const paginationVariables = getPaginationVariables(request, {
16
16
  pageBy: 4,
17
17
  });
@@ -1,12 +1,15 @@
1
- import {json, type LoaderArgs} from '@shopify/remix-oxygen';
2
- import {Link, useLoaderData, type V2_MetaFunction} from '@remix-run/react';
1
+ import {json, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
2
+ import {Link, useLoaderData, type MetaFunction} from '@remix-run/react';
3
3
  import {Pagination, getPaginationVariables} from '@shopify/hydrogen';
4
4
 
5
- export const meta: V2_MetaFunction = () => {
5
+ export const meta: MetaFunction = () => {
6
6
  return [{title: `Hydrogen | Blogs`}];
7
7
  };
8
8
 
9
- export const loader = async ({request, context: {storefront}}: LoaderArgs) => {
9
+ export const loader = async ({
10
+ request,
11
+ context: {storefront},
12
+ }: LoaderFunctionArgs) => {
10
13
  const paginationVariables = getPaginationVariables(request, {
11
14
  pageBy: 10,
12
15
  });
@@ -1,4 +1,4 @@
1
- import {redirect, type LoaderArgs} from '@shopify/remix-oxygen';
1
+ import {redirect, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
2
2
 
3
3
  /**
4
4
  * Automatically creates a new cart based on the URL and redirects straight to checkout.
@@ -18,7 +18,7 @@ import {redirect, type LoaderArgs} from '@shopify/remix-oxygen';
18
18
  *
19
19
  * ```
20
20
  */
21
- export async function loader({request, context, params}: LoaderArgs) {
21
+ export async function loader({request, context, params}: LoaderFunctionArgs) {
22
22
  const {cart} = context;
23
23
  const {lines} = params;
24
24
  if (!lines) return redirect('/cart');
@@ -1,16 +1,16 @@
1
- import {Await, useMatches, type V2_MetaFunction} from '@remix-run/react';
1
+ import {Await, type MetaFunction} from '@remix-run/react';
2
2
  import {Suspense} from 'react';
3
3
  import type {CartQueryData} from '@shopify/hydrogen';
4
4
  import {CartForm} from '@shopify/hydrogen';
5
- import {type ActionArgs, json} from '@shopify/remix-oxygen';
6
- import type {CartApiQueryFragment} from 'storefrontapi.generated';
5
+ import {json, type ActionFunctionArgs} from '@shopify/remix-oxygen';
7
6
  import {CartMain} from '~/components/Cart';
7
+ import {useRootLoaderData} from '~/root';
8
8
 
9
- export const meta: V2_MetaFunction = () => {
9
+ export const meta: MetaFunction = () => {
10
10
  return [{title: `Hydrogen | Cart`}];
11
11
  };
12
12
 
13
- export async function action({request, context}: ActionArgs) {
13
+ export async function action({request, context}: ActionFunctionArgs) {
14
14
  const {session, cart} = context;
15
15
 
16
16
  const [formData, customerAccessToken] = await Promise.all([
@@ -85,14 +85,17 @@ export async function action({request, context}: ActionArgs) {
85
85
  }
86
86
 
87
87
  export default function Cart() {
88
- const [root] = useMatches();
89
- const cart = root.data?.cart as Promise<CartApiQueryFragment | null>;
88
+ const rootData = useRootLoaderData();
89
+ const cartPromise = rootData.cart;
90
90
 
91
91
  return (
92
92
  <div className="cart">
93
93
  <h1>Cart</h1>
94
94
  <Suspense fallback={<p>Loading cart ...</p>}>
95
- <Await errorElement={<div>An error occurred</div>} resolve={cart}>
95
+ <Await
96
+ resolve={cartPromise}
97
+ errorElement={<div>An error occurred</div>}
98
+ >
96
99
  {(cart) => {
97
100
  return <CartMain layout="page" cart={cart} />;
98
101
  }}
@@ -1,5 +1,5 @@
1
- import {json, redirect, type LoaderArgs} from '@shopify/remix-oxygen';
2
- import {useLoaderData, Link, type V2_MetaFunction} from '@remix-run/react';
1
+ import {json, redirect, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
2
+ import {useLoaderData, Link, type MetaFunction} from '@remix-run/react';
3
3
  import {
4
4
  Pagination,
5
5
  getPaginationVariables,
@@ -9,11 +9,11 @@ import {
9
9
  import type {ProductItemFragment} from 'storefrontapi.generated';
10
10
  import {useVariantUrl} from '~/utils';
11
11
 
12
- export const meta: V2_MetaFunction = ({data}) => {
13
- return [{title: `Hydrogen | ${data.collection.title} Collection`}];
12
+ export const meta: MetaFunction<typeof loader> = ({data}) => {
13
+ return [{title: `Hydrogen | ${data?.collection.title ?? ''} Collection`}];
14
14
  };
15
15
 
16
- export async function loader({request, params, context}: LoaderArgs) {
16
+ export async function loader({request, params, context}: LoaderFunctionArgs) {
17
17
  const {handle} = params;
18
18
  const {storefront} = context;
19
19
  const paginationVariables = getPaginationVariables(request, {
@@ -1,9 +1,9 @@
1
1
  import {useLoaderData, Link} from '@remix-run/react';
2
- import {json, type LoaderArgs} from '@shopify/remix-oxygen';
2
+ import {json, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
3
3
  import {Pagination, getPaginationVariables, Image} from '@shopify/hydrogen';
4
4
  import type {CollectionFragment} from 'storefrontapi.generated';
5
5
 
6
- export async function loader({context, request}: LoaderArgs) {
6
+ export async function loader({context, request}: LoaderFunctionArgs) {
7
7
  const paginationVariables = getPaginationVariables(request, {
8
8
  pageBy: 4,
9
9
  });
@@ -1,4 +1,4 @@
1
- import {redirect, type LoaderArgs} from '@shopify/remix-oxygen';
1
+ import {redirect, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
2
2
 
3
3
  /**
4
4
  * Automatically applies a discount found on the url
@@ -11,7 +11,7 @@ import {redirect, type LoaderArgs} from '@shopify/remix-oxygen';
11
11
  *
12
12
  * ```
13
13
  */
14
- export async function loader({request, context, params}: LoaderArgs) {
14
+ export async function loader({request, context, params}: LoaderFunctionArgs) {
15
15
  const {cart} = context;
16
16
  const {code} = params;
17
17
 
@@ -1,11 +1,11 @@
1
- import {json, type LoaderArgs} from '@shopify/remix-oxygen';
2
- import {useLoaderData, type V2_MetaFunction} from '@remix-run/react';
1
+ import {json, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
2
+ import {useLoaderData, type MetaFunction} from '@remix-run/react';
3
3
 
4
- export const meta: V2_MetaFunction = ({data}) => {
5
- return [{title: `Hydrogen | ${data.page.title}`}];
4
+ export const meta: MetaFunction<typeof loader> = ({data}) => {
5
+ return [{title: `Hydrogen | ${data?.page.title ?? ''}`}];
6
6
  };
7
7
 
8
- export async function loader({params, context}: LoaderArgs) {
8
+ export async function loader({params, context}: LoaderFunctionArgs) {
9
9
  if (!params.handle) {
10
10
  throw new Error('Missing page handle');
11
11
  }
@@ -1,5 +1,5 @@
1
- import {json, type LoaderArgs} from '@shopify/remix-oxygen';
2
- import {Link, useLoaderData, type V2_MetaFunction} from '@remix-run/react';
1
+ import {json, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
2
+ import {Link, useLoaderData, type MetaFunction} from '@remix-run/react';
3
3
  import {type Shop} from '@shopify/hydrogen/storefront-api-types';
4
4
 
5
5
  type SelectedPolicies = keyof Pick<
@@ -7,11 +7,11 @@ type SelectedPolicies = keyof Pick<
7
7
  'privacyPolicy' | 'shippingPolicy' | 'termsOfService' | 'refundPolicy'
8
8
  >;
9
9
 
10
- export const meta: V2_MetaFunction = ({data}) => {
11
- return [{title: `Hydrogen | ${data.policy.title}`}];
10
+ export const meta: MetaFunction<typeof loader> = ({data}) => {
11
+ return [{title: `Hydrogen | ${data?.policy.title ?? ''}`}];
12
12
  };
13
13
 
14
- export async function loader({params, context}: LoaderArgs) {
14
+ export async function loader({params, context}: LoaderFunctionArgs) {
15
15
  if (!params.handle) {
16
16
  throw new Response('No handle was passed in', {status: 404});
17
17
  }
@@ -1,7 +1,7 @@
1
- import {json, type LoaderArgs} from '@shopify/remix-oxygen';
1
+ import {json, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
2
2
  import {useLoaderData, Link} from '@remix-run/react';
3
3
 
4
- export async function loader({context}: LoaderArgs) {
4
+ export async function loader({context}: LoaderFunctionArgs) {
5
5
  const data = await context.storefront.query(POLICIES_QUERY);
6
6
  const policies = Object.values(data.shop || {});
7
7
 
@@ -1,10 +1,10 @@
1
1
  import {Suspense} from 'react';
2
- import {defer, redirect, type LoaderArgs} from '@shopify/remix-oxygen';
2
+ import {defer, redirect, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
3
3
  import {
4
4
  Await,
5
5
  Link,
6
6
  useLoaderData,
7
- type V2_MetaFunction,
7
+ type MetaFunction,
8
8
  type FetcherWithComponents,
9
9
  } from '@remix-run/react';
10
10
  import type {
@@ -27,11 +27,11 @@ import type {
27
27
  } from '@shopify/hydrogen/storefront-api-types';
28
28
  import {getVariantUrl} from '~/utils';
29
29
 
30
- export const meta: V2_MetaFunction = ({data}) => {
31
- return [{title: `Hydrogen | ${data.product.title}`}];
30
+ export const meta: MetaFunction<typeof loader> = ({data}) => {
31
+ return [{title: `Hydrogen | ${data?.product.title ?? ''}`}];
32
32
  };
33
33
 
34
- export async function loader({params, request, context}: LoaderArgs) {
34
+ export async function loader({params, request, context}: LoaderFunctionArgs) {
35
35
  const {handle} = params;
36
36
  const {storefront} = context;
37
37
 
@@ -74,7 +74,7 @@ export async function loader({params, request, context}: LoaderArgs) {
74
74
  // if no selected variant was returned from the selected options,
75
75
  // we redirect to the first variant's url with it's selected options applied
76
76
  if (!product.selectedVariant) {
77
- return redirectToFirstVariant({product, request});
77
+ throw redirectToFirstVariant({product, request});
78
78
  }
79
79
  }
80
80
 
@@ -100,7 +100,7 @@ function redirectToFirstVariant({
100
100
  const url = new URL(request.url);
101
101
  const firstVariant = product.variants.nodes[0];
102
102
 
103
- throw redirect(
103
+ return redirect(
104
104
  getVariantUrl({
105
105
  pathname: url.pathname,
106
106
  handle: product.handle,
@@ -1,14 +1,14 @@
1
- import {defer, type LoaderArgs} from '@shopify/remix-oxygen';
2
- import {useLoaderData, type V2_MetaFunction} from '@remix-run/react';
1
+ import {defer, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
2
+ import {useLoaderData, type MetaFunction} from '@remix-run/react';
3
3
  import {getPaginationVariables} from '@shopify/hydrogen';
4
4
 
5
5
  import {SearchForm, SearchResults, NoSearchResults} from '~/components/Search';
6
6
 
7
- export const meta: V2_MetaFunction = () => {
7
+ export const meta: MetaFunction = () => {
8
8
  return [{title: `Hydrogen | Search`}];
9
9
  };
10
10
 
11
- export async function loader({request, context}: LoaderArgs) {
11
+ export async function loader({request, context}: LoaderFunctionArgs) {
12
12
  const url = new URL(request.url);
13
13
  const searchParams = new URLSearchParams(url.search);
14
14
  const variables = getPaginationVariables(request, {pageBy: 8});
@@ -46,6 +46,7 @@ export async function loader({request, context}: LoaderArgs) {
46
46
 
47
47
  export default function SearchPage() {
48
48
  const {searchTerm, searchResults} = useLoaderData<typeof loader>();
49
+
49
50
  return (
50
51
  <div className="search">
51
52
  <h1>Search</h1>