Add product description pages

So far, your marketplace UI includes a homepage that displays shops and some of their products. Each shop in the marketplace has a dedicated page that shows the types of products they sell. However, to see product details, buyers need to select products and be redirected to the merchant's storefront. Instead, you want your marketplace to provide the information that buyers might need to make a purchase.

In this tutorial, you'll use dynamic routing that directs buyers to a unique URL for each product on the shop's page. You'll use the Storefront API to surface product details onto product description pages. The pages will include product variant pickers, and page content will dynamically update to reflect a selected variant.

An image of the product page featuring LED high tops and a size dropdown list

What you'll learn

After you finish this tutorial, you'll know how to do the following:

  • Link out from a product on an shop page to a product description page

  • Surface product descriptions from the shop on a marketplace

  • Dynamically update product details when selected variants change

Requirements

  • You've completed the Shops tutorials.

Previously, you created a generic ProductTile component for rendering different shops and their products. In this step, you'll augment the component to render a link to a new marketplace product description page.

  1. In components/productGrid.js, add handle and shopId properties and use next/link to construct a URL with the shop ID and product handle.

  2. Add a shopId property to the ProductGrid component, and pass that through to each product tile.

    Because you're spreading elements from the products array into the ProductTile component, the handle will be included if it's provided by the ProductGrid parent.

Step 2: Update product grid consumers

Because you've updated the ProductGrid component properties, you need to update the marketplace homepage and shop page to pass in the correct data.

  1. In pages/index.js, add handle to the product query, and pass the shopId to the ProductGrid component.

    The marketplace homepage should now look something like the following:

    An image of the marketplace homepage where products include a link to view product details

  2. In pages/shops/[id].js, update the products query to retrieve the handle field.

    This ensures that each product's handle is passed through the products array to the ProductGrid component.

    You should also update the PaginatedProducts component to get the id from the router query and pass it into the ProductGrid component.

    The shop page should now look something like the following:

    An image of the shop page where products include a link to view product details

Step 3: Set up the product page

Now that you've added links to the product description page from the marketplace homepage and shop page, you can start building the page contents. You'll need to update your /pages folder structure to fit the path structure of the URL. For example, since the links you added begin with /products, you'll need to add a products folder to /pages.

  1. In /pages, create the following directory structure:

    The [shopid] folder represents a dynamic route enabling you to use the shop ID as a URL subpath.

    The [producthandle].js file represents a dynamic route enabling you to use the product handle as a URL subpath.

  2. In pages/products/[shopid]/[producthandle].js, create a basic component to verify that you're getting the shop ID and product handle from the router query.

  3. Add a query to retrieve the shop domain and Storefront API access token, given an ID, and call it from an effect.

    You'll use the shop field (shop($id: ID!)) that you added when you added shop pages. You can use the retrieved domain and Storefront API access token to create an ApolloClient and store it in the component's state, so that it's available to make subsequent requests for product information.

  4. Use the shopClient from the component's state to retrieve product details and store the details in the component's state.

  5. Use the product details to render a basic product page, and set up the scaffolding for a tab UI.

    The tab UI will hold additional descriptive content and details, and you'll update this with shop details like shipping policies.

    You should now have a basic product page that looks something like the following:

    An image of the product page featuring LED high tops and a specifications tab with a product description

Step 4: Add variant selection

Products can have one or more variants, which may have their own image and price. Each variant is tied to merchant-configured product options. To enable buyers to explore all variants, they need to be able to select product options.

  1. In pages/products/[shopid]/[producthandle].js, update the product query to retrieve variant information and product options.

  2. Update the Product component's state to track the selected options and selected variant details.

    You'll also add an effect to select the first variant and its option after the Storefront API returns the product.

  3. Use the product's options to return the list of product options names and available values, and memoize the returned object with the useMemo hook.

  4. Use the memoized object to build the markup for a set of option selectors, which update the selected variants and options in the component's state.

    You'll render the selectors below the product title on the product page.

    The product description page should now have variant selectors and look something like the following:

    An image of the product page featuring LED high tops and a size dropdown list

  5. Render the details from the selected variant to the product page.

    The product description page should now have variant selectors, and dynamically update the price and image to the selected variant. It should look something like the following:

    An image of the product page featuring LED high tops and a selected variant

Next steps

  • Learn how to add a Buy Now button to shop pages, to take buyers directly from a product to checkout.