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:

Code
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:

Code
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?
Edit this page
Ask Anything
FAQ
What is Medusa?
How can I create a module?
How can I create a data model?
How do I create a workflow?
How can I extend a data model in the Product Module?
Recipes
How do I build a marketplace with Medusa?
How do I build digital products with Medusa?
How do I build subscription-based purchases with Medusa?
What other recipes are available in the Medusa documentation?
Chat is cleared on refresh
Line break