- Get Started
- Product
- Resources
- Tools & SDKs
- Framework
- Reference
Menu
- Get Started
- Product
- Resources
- Tools & SDKs
- Framework
- Reference
List Products in Storefront
In this document, learn how to list, paginate, and filter products in the storefront.
List Products#
To list products, send a request to the List Products API route:
The response has a products
field, which is an array of products.
Paginate Products#
To paginate products, pass the following query parameters:
limit
: The number of products to return in the request.offset
: The number of products to skip before the returned products. You can calculate this by multiplying the current page with the limit.
The response object returns a count
field, which is the total count of products. Use it to determine whether there are more products that can be loaded.
For example:
1"use client" // include with Next.js 13+2 3import { useEffect, useState } from "react"4import { HttpTypes } from "@medusajs/types"5 6export default function Products() {7 const [loading, setLoading] = useState(true)8 const [products, setProducts] = useState<9 HttpTypes.StoreProduct[]10 >([])11 const limit = 2012 const [currentPage, setCurrentPage] = useState(1)13 const [hasMorePages, setHasMorePages] = useState(false)14 15 useEffect(() => {16 if (!loading) {17 return 18 }19 20 const offset = (currentPage - 1) * limit21 22 const searchParams = new URLSearchParams({23 limit: `${limit}`,24 offset: `${offset}`,25 })26 27 fetch(`http://localhost:9000/store/products?${searchParams.toString()}`, {28 credentials: "include",29 headers: {30 "x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY || "temp",31 },32 })33 .then((res) => res.json())34 .then(({ products: dataProducts, count }) => {35 setProducts((prev) => {36 if (prev.length > offset) {37 // products already added because the same request has already been sent38 return prev39 }40 return [41 ...prev,42 ...dataProducts,43 ]44 })45 setHasMorePages(count > limit * currentPage)46 setLoading(false)47 })48 }, [loading])49 50 return (51 <div>52 {loading && <span>Loading...</span>}53 {!loading && products.length === 0 && <span>No products found.</span>}54 {!loading && products.length > 0 && (55 <ul>56 {products.map((product) => (57 <li key={product.id}>{product.title}</li>58 ))}59 </ul>60 )}61 {!loading && hasMorePages && (62 <button63 onClick={() => {64 setCurrentPage((prev) => prev + 1)65 setLoading(true)66 }}67 disabled={loading}68 >69 Load More70 </button>71 )}72 </div>73 )74}
Filter Products#
The List Products API route accepts query parameters to filter products by title, category, whether they're a gift card, and more.
Refer to the API reference for the list of accepted query parameters.
For example, to run a query on the products:
1const searchParams = new URLSearchParams({2 // other params...3 q: "Shirt",4})5 6fetch(`http://localhost:9000/store/products?${searchParams.toString()}`, {7 credentials: "include",8 headers: {9 "x-publishable-api-key": process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY || "temp",10 },11})12.then((res) => res.json())13.then(({ products: dataProducts, count }) => {14 // TODO set products...15})
Was this page helpful?