Vue Storefront is now Alokai! Learn More
Product List

Product List

The Product List module is a powerful and flexible feature designed to enhance the user experience on your e-commerce platform. It provides an alternative view for product listings on category pages, replacing the traditional grid view with a sleek and efficient list view.

Featuresri:link

  • List View Display: The primary function of the "Product List" module is to present your products in a clean and organized list view. This format offers a streamlined approach to product discovery, allowing users to focus on product details without the distraction of a grid layout.
  • ProductCardListView Component: A crucial element of this module is the "ProductCardListView" component. This component is responsible for rendering each product in the list view. It provides a rich, interactive, and informative display of product information, including images, titles, prices, and other relevant details.
  • Enhanced User Experience: By offering a list view, this module caters to users who prefer a more linear and concise presentation of products.
  • Responsive Design: The "Product List" module ensures that the list view is responsive and adapts to different screen sizes and devices, maintaining a seamless shopping experience on both desktop and mobile platforms.

Installationri:link

Add the module filesri:link

To install the module, you need an enterprise license and credentials. Contact your Customer Support Manager if you're already a customer. If you're not a customer yet, contact Alokai Sales Team.

From the root of your project run the following command:

npx @vsf-enterprise/storefront-cli add-module product-list

Follow the instructions in the command line to complete the installation. To make sure the installation is finished, go to the apps/storefront-middleware/sf-modules folder and check if there's a folder named product-list inside.

Frontend Implementationri:link

Once installed, you will be able to use the <ProductList /> component throughout your app.

The simplest usage of this module is to replace current grid view with the module on category pages. To do so, you need to import the <ProductList /> component and pass the products array to it.

// components/products-listing/products-listing-page.tsx

import { ProductList as ProductListSection } from '@sf-modules/product-list'; // ...

export default function ProductsListingPage({...}: ProductsListingPageProps) {

  return (
    <div>
      // ...
        <ProductListSection products={products}/>        <section          className={classNames(             'col-span-full mb-10 grid grid-cols-1 gap-4 2-extra-small:grid-cols-2 lg:mb-10 lg:mt-10 lg:grid-cols-3 lg:gap-6 2xl:grid-cols-4',             hideFilters ? 'lg:col-span-full' : 'lg:col-start-2 lg:row-start-1',           )}          data-testid="category-grid"        >          {products.length === 0 && slotEmptyState}          <ProductsList products={products} />          {products.length > 0 && (             <Pagination              className="col-span-full mt-4"              currentPage={currentPage}              pageSize={pageSize ?? 24}              totalResults={totalResults}            />           )}        </section>      // ...
    </div>
  );
};

More advanced usage of the module includes a switch that allows users to toggle between grid and list views. To implement this feature without any extra UI you can use the query parameter in the URL, f.e. ?view=list. Then you can use the searchParams prop for next14 to get the value of the view parameter and conditionally render the <ProductList /> component.

// app/[locale]/(default)/category/[[...slugs]]/page.tsx

export default async function CategoryPage({ params, searchParams }: CategoryPageProps) {
  // ...
  return (
    <div className="px-4 pt-4 lg:px-0">
      // ...
      <ProductsListingPage
        // ...
        title={categoryTitle}
        searchParams={searchParams}      />
    </div>
  );
}
// components/products-listing/products-listing-page.tsx

import { ProductList as ProductListSection } from '@sf-modules/product-list'; // ...
export interface ProductsListingPageProps {  searchParams: { [key: string]: string | string[] | undefined };  // ...
}
// ...

export default function ProductsListingPage({
    // ...,
    searchParams  }: ProductsListingPageProps) {
  const listPageView = searchParams?.view === 'list'; 
  return (
    <div>
      // ...
        {listPageView ? (          <ProductListSection products={products} />        ) : (          <section
            className={classNames(
              'col-span-full mb-10 grid grid-cols-1 gap-4 2-extra-small:grid-cols-2 lg:mb-10 lg:mt-10 lg:grid-cols-3 lg:gap-6 2xl:grid-cols-4',
              hideFilters ? 'lg:col-span-full' : 'lg:col-start-2 lg:row-start-1',
            )}
            data-testid="category-grid"
          >
            {products.length === 0 && slotEmptyState}
            <ProductsList products={products} />
            {products.length > 0 && (
              <Pagination
                className="col-span-full mt-4"
                currentPage={currentPage}
                pageSize={pageSize ?? 24}
                totalResults={totalResults}
              />
            )}
          </section>
        )}
      // ...
    </div>
  );
};