CoursesSanity and Shopify with HydrogenFetching Shopify products

Sanity and Shopify with Hydrogen

Lesson
5

Fetching Shopify products

Log in to mark your progress for each Lesson and Task

With the Hydrogen app connected to Shopify, next you'll need to create “routes” to fetch and display products.

For a more functional Hydrogen app, we’ll need these three new route documents.

If you get stuck or for more details, see the Remix documentation on routes
Create a home page route with a link to the product index page.
./app/routes/_index.tsx
import {Link} from '@remix-run/react';
export default function Index() {
return (
<div className="mx-auto p-12 prose prose-xl prose-a:text-blue-500">
<h1 className="text-3xl font-bold">Home</h1>
<p>
<Link className="text-blue-500 underline" to="/products">
All Products
</Link>
</p>
</div>
);
}

The home page of your Hydrogen App should look much like the image below.

You can click the “All Products” link, but it will 404.

This route uses Remix's loader function convention to query data on the server and pass it down to the client.

Hydrogen has a preconfigured storefront variable which is available to all loaders via the context variable. This is explained further in the next exercise.

Using storefront, queries to Shopify can be performed.

Create a products index route
./app/routes/products._index.tsx
import {json, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
import {Link, useLoaderData} from '@remix-run/react';
import type {Product} from '@shopify/hydrogen/storefront-api-types';
export async function loader({context: {storefront}}: LoaderFunctionArgs) {
const {products} = await storefront.query<{products: {nodes: Product[]}}>(
`#graphql
query Products {
products(first: 10) {
nodes { id title handle }
}
}
`,
);
if (!products.nodes.length) {
throw new Response('Not found', {status: 404});
}
return json({products: products.nodes});
}
export default function Index() {
const {products} = useLoaderData<typeof loader>();
return (
<div className="mx-auto p-12 prose prose-xl prose-a:text-blue-500">
<h1 className="text-3xl font-bold">All Products</h1>
{products.map((product) => (
<p key={product.id}>
<Link to={`/products/${product.handle}`}>{product.title}</Link>
</p>
))}
</div>
);
}

Visit /products on your Hydrogen store now, you should see a list of up to 10 products with links to their individual product pages.

These will return 404 if you click them; let’s fix that.

This route below also uses the same loader to fetch data but also takes advantage of the variable $handle to find a specific product.

Create a new product page
./app/routes/products.$handle.tsx
import {json, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
import {Link, useLoaderData} from '@remix-run/react';
import type {Product} from '@shopify/hydrogen/storefront-api-types';
export async function loader({
params,
context: {storefront},
}: LoaderFunctionArgs) {
const {product} = await storefront.query<{product: Product}>(
`#graphql
query Product($handle: String!) {
product(handle: $handle) { id title }
}
`,
{
variables: {handle: params.handle},
},
);
return json({product});
}
export default function Page() {
const {product} = useLoaderData<typeof loader>();
return (
<div className="mx-auto p-12 prose prose-xl prose-a:text-blue-500">
<h1 className="text-3xl font-bold">{product.title}</h1>
<Link to="/products">&larr; Back to All Products</Link>
</div>
);
}

Now you should be able to view a specific product from the /products page and click through.

If your site looks like this, congratulations! Your Hydrogen app now queries Shopify content directly from your store.

What you don’t have is the additional content from your Sanity Studio. Let’s fix that next.

You have 3 uncompleted tasks in this lesson
0 of 3