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.
Features
- 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.
Installation
Add the module files
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 Implementation
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>
);
};