Building the Product List Page
Overview
The Product List Page (PLP) is the page that displays a list of products to your end users. This guide will explore how to build a PLP using the Merchstack API.
Before we get started, we are assuming that you have already set up your project to access the Merchstack API. If you have not, please refer to the Accessing the API section of the documentation.
Product Listing Page
The following is a step-by-step guide to creating a basic product listing page using the Merchstack API.
Step 1: Create a Product Listing Component
The first step is to create a component that will be responsible for displaying the products. This component will be responsible for making the API call to Merchstack and displaying the results. Create a new file called ProductListing.jsx and add the following code:
import React from 'react' import { useQuery, gql } from '@apollo/client' const GET_PRODUCTS = gql` query AlternativeSearch($input: AlternativeSearchInput!) { alternativeSearch(input: $input) { items { name slug brand variants { name sku stockLevel asset { preview } lineage id } price { ...on PriceRange { min max } } compareAtPrice { ...on PriceRange { min max } } id lineage code stockLevel score asset { id preview } slug categoryIds } totalItems } } ` function ProductListing() { const { loading, error, data } = useQuery(GET_PRODUCTS, { variables: { input: { inStock: true, take: 10, skip: 0, }, }, }) if (loading) return <p>Loading...</p> if (error) return <p>Error :(</p> return data.alternativeSearch.items.map(({ id, name }) => ( <div key={id}> <p>{name}</p> </div> )) } export default ProductListing
In the above code, we are using the useQuery hook to make a call to the Merchstack API. We are using the alternativeSearch query to retrieve a list of products. The alternativeSearch query is a powerful query that allows you to search for products based on a variety of criteria.
The alternativeSearch query returns a list of products. For each product, we are displaying the name of the product. You can display any of the other fields that are returned by the alternativeSearch query.
You can modify the component to display the products in any way you please. For example, you could display the products in a grid, table or a list. You could also add pagination to the component to allow the user to navigate through the list of products.
Although, you have the liberty to display the products in any way you please, we have created a sample product card/tile component that you can use to display the products. You can find the component by visiting Product Tile/Card file. You can import the component and use it in your ProductListing component.
You can handle pagination using the skip and take arguments of the alternativeSearch query. We also return the totalItems field from the alternativeSearch query helpful for pagination. Below is the sample code for pagination with page numbers, next, previous, first and last buttons.
import React, { useState } from 'react' import { useQuery, gql } from '@apollo/client' const GET_PRODUCTS = gql` query AlternativeSearch($input: AlternativeSearchInput!) { alternativeSearch(input: $input) { items { name slug brand variants { name sku stockLevel asset { preview } lineage id } price { ...on PriceRange { min max } } compareAtPrice { ...on PriceRange { min max } } id lineage code stockLevel score asset { id preview } slug categoryIds } totalItems } } ` function ProductListing() { const [skip, setSkip] = useState(0) const [take, setTake] = useState(10) const { loading, error, data } = useQuery(GET_PRODUCTS, { variables: { input: { inStock: true, take, skip, }, }, }) if (loading) return <p>Loading...</p> if (error) return <p>Error :(</p> return ( <> {data.alternativeSearch.items.map(({ id, name }) => ( <div key={id}> <p>{name}</p> </div> ))} <div className="flex justify-center items-center"> <button className="bg-gray-200 hover:bg-gray-300 text-gray-800 font-bold py-2 px-4 rounded-l" onClick={() => { setSkip(0) } }> First </button> <button className="bg-gray-200 hover:bg-gray-300 text-gray-800 font-bold py-2 px-4 rounded-l" onClick={() => { if (skip > 0) { setSkip(skip - take) } }} > Previous </button> <p className="mr-4">Page {skip / take + 1}</p> <button className="bg-gray-200 hover:bg-gray-300 text-gray-800 font-bold py-2 px-4 rounded-r" onClick={() => { if (skip + take < data.alternativeSearch.totalItems) { setSkip(skip + take) } }} > Next </button> <button className="bg-gray-200 hover:bg-gray-300 text-gray-800 font-bold py-2 px-4 rounded-r" onClick={() => { setSkip(data.alternativeSearch.totalItems - take) }} > Last </button> </div> </> ) } export default ProductListing
Step 2 (optional): Add the Product Listing Component to a Page
The next step is to add the ProductListing component to a page. Create a new file called ProductListingPage.jsx and add the following code:
import React from 'react' import ProductListing from './ProductListing' function ProductListingPage() { return ( <div> <ProductListing /> </div> ) } export default ProductListingPage
In the above code, we are simply rendering the ProductListing component. You can pass the desired options to the alternativeSearch query as props to the ProductListing component. For example, if you wanted to display 20 products instead of 10, you could pass the take prop to the ProductListing component. The idea is to make the ProductListing component as flexible as possible so that it can be used in a variety of different scenarios.
This is an optional step. You can skip this step and create or import the ProductListing component to your components/containers/page directly if you prefer.
Step 3 (optional): Add the Product Listing Page to the Router
The final step is to add the ProductListingPage component to the router. Open the App.jsx file and add the following code:
import React from 'react' import { BrowserRouter as Router, Switch, Route } from 'react-router-dom' import ProductListingPage from './ProductListingPage' function App() { return ( <Router> <Switch> <Route path="/"> <ProductListingPage /> </Route> </Switch> </Router> ) } export default App
In the above code, we are adding the ProductListingPage component to the router. Now when you navigate to the root of your application, you should see a list of products.
This is an optional step. You can skip this step and hook to the application router as per your preference.
More Information on Alternate Search
The alternativeSearch query is a powerful query that allows you to search for products based on a variety of criteria. For more information on the alternativeSearch query or any other queries, please refer to the GraphQL Playground -> Docs -> alternativeSearch
We will keep referring to the alternativeSearch query throughout the storefront integration documentation. It is important to understand how to use this query. We recommend that you spend some time familiarizing yourself with the query.