Skip to content
Guides

Catalog and search

Query products, facets, details, related items, and autocomplete with serverApi.

Last updated:

serverApi runs Storefront API queries as server functions. Use it in loaders to return HTML with data in the first response.

Results page

pages/products.index.tsx
import {
  definePage,
  serverApi,
  z,
  type ProductsResponse,
} from "@ecomiq/storefront";

const ProductSearchSchema = z.object({
  q: z.string().optional(),
  page: z.coerce.number().int().positive().catch(1),
});

type ProductSearch = z.infer<typeof ProductSearchSchema>;

export default definePage<
  ProductsResponse,
  Record<string, string>,
  ProductSearch
>({
  validateSearch: (raw) => ProductSearchSchema.parse(raw),
  loader: ({ search }) =>
    serverApi.getProducts({
      search: search.q,
      page: search.page,
      pageSize: 24,
    }),
  meta: ({ search }) => ({
    title: search.q ? `Results for ${search.q}` : "Products",
  }),
  component: ({ data }) => (
    <section>
      <h1>{data.totalCount} products</h1>
      {data.products.map((product) => (
        <article key={product.id}>
          <h2>{product.name}</h2>
          <p>{product.price}</p>
        </article>
      ))}
    </section>
  ),
});

Methods

MethodResult
serverApi.getProducts(params)Paginated products and facets.
serverApi.getProductBySlug(slug)Product details.
serverApi.getRelatedProducts(params)Related products.
serverApi.autocompleteProducts(params)Short search suggestions.
serverApi.getCollections()Visible collections.
serverApi.getCollectionBySlug(slug)One collection by slug.

Product filters

getProducts accepts:

  • page — defaults to 1.
  • pageSize — defaults to 24, maximum 100.
  • sort — priceAsc, priceDesc, nameAsc, nameDesc, or newest.
  • search, productIds, and sellers (seller slugs).
  • collections and collectionId.
  • categories, brands, productTypes, and tags.
  • filters, inStock, minPrice, and maxPrice.

The response contains pageIndex, pageSize, totalCount, totalPages, products, and filters.

Autocomplete

lib/search.ts
const suggestions = await serverApi.autocompleteProducts({
  search: "cof",
  limit: 8,
});

search must contain 2 to 80 characters. limit defaults to 8 and cannot exceed 20.

No direct browser requests

In Ecomiq pages, prefer serverApi. It keeps the upstream URL and operational headers out of the client bundle.

On this page