Search Products
About
Search the catalog by keyword. Pass a query argument to the products field:
products(query: "shirt", first: 10)A product matches when the keyword appears anywhere in its name or its SKU. Partial words count — searching cott returns every product whose name contains Cotton.
This is the same field that powers List Products. Results come back in the same shape as a listing, so both screens render with the same code, and filtering, sorting, and pagination work identically. Use it to:
- Implement product search over the catalog
- Build auto-complete and suggestion interfaces
- Narrow a search further by category, type, price range, or attribute
- Order search results by title, price, or date
The sections below cover what matters on a search screen. List Products carries the full argument reference.
Arguments
| Argument | Type | Description |
|---|---|---|
query | String | Search term. Matched as a partial string against the product name and SKU. Descriptions and attribute values are not searched. |
first | Int | Number of results per page. Default: 30 |
after | String | Cursor for pagination. Returns results after this cursor. |
last | Int | Number of results for backward pagination. Default: 30 |
before | String | Cursor for backward pagination. |
sortKey | String | Sort results by: ID, TITLE (alias NAME), PRICE, CREATED_AT, UPDATED_AT. Case-insensitive. Default: ID |
reverse | Boolean | Reverse sort order. Default: false |
filter | String | JSON-encoded filter string. Accepts type, sku, category_id, price_from, price_to, new, featured, and any filterable attribute code (e.g. "{\"category_id\": \"22\"}"). |
Possible Returns
| Field | Type | Description |
|---|---|---|
edges | [ProductEdge] | Search result edges containing product nodes and pagination cursors. |
edges.node | Product | The matched product, carrying the same fields as any catalog listing row. |
edges.cursor | String | Pagination cursor for this result. |
pageInfo | ProductPageInfo! | Pagination metadata. |
pageInfo.hasNextPage | Boolean | Whether more results follow the current page. |
pageInfo.hasPreviousPage | Boolean | Whether results precede the current page. |
pageInfo.startCursor | String | Cursor of the first result on the page. |
pageInfo.endCursor | String | Cursor of the last result on the page. |
totalCount | Int! | Total matching products across all pages. |
Narrowing a Search
A search accepts the same filter argument as the listing, so a keyword and a category or attribute selection combine into one request:
query searchInCategory($query: String, $filter: String) {
products(query: $query, filter: $filter, first: 10) {
totalCount
edges {
node {
_id
sku
name
formattedPrice
}
}
}
}{
"query": "shirt",
"filter": "{\"type\": \"configurable\", \"color\": \"3\"}"
}The keyword and every filter key intersect — each one narrows the result further. The complete key list, the escaping rules, and the price-range caveats are on List Products.
Ordering Search Results
Search results are not ranked by relevance. Every match is returned in the order given by sortKey, and omitting it falls back to product ID — effectively arbitrary for a shopper. A search screen should therefore always set an explicit order, most often TITLE ascending or PRICE ascending.
The available sort keys, their reverse combinations, and the reason PRICE orders on minimumPrice rather than price are documented on List Products.
REST API Equivalents
| Use Case | REST Endpoint | GraphQL Equivalent |
|---|---|---|
| Keyword search | /api/shop/products?query=shirt&per_page=10 | products(query: "shirt", first: 10) |
| New Products | /api/shop/products?new=1&sort=created_at-desc&per_page=10 | products(filter: "{\"new\": \"1\"}", sortKey: "CREATED_AT", reverse: true, first: 10) |
| Featured Products | /api/shop/products?featured=1&sort=created_at-desc&per_page=12 | products(filter: "{\"featured\": \"1\"}", sortKey: "CREATED_AT", reverse: true, first: 12) |
| Popular by Brand | /api/shop/products?brand=25&sort=created_at-desc&per_page=12 | products(filter: "{\"brand\": \"25\"}", sortKey: "CREATED_AT", reverse: true, first: 12) |
| All (Price Desc) | /api/shop/products?sort=price-desc&per_page=12 | products(sortKey: "PRICE", reverse: true, first: 12) |

