Overview
Spree provides powerful search, filtering, and sorting capabilities for products and other resources. The Store API supports:
- Full-text search across product names, descriptions, and SKUs
- Attribute-based filtering (price range, availability, stock status)
- Category and taxon filtering
- Faceted search with filter counts
- Flexible sorting options
Product Search
Use the multi_search parameter for full-text search across product fields:
const { data: products } = await client.products.list({
multi_search: 'tote bag',
limit: 12,
})
Filtering Products
By Price Range
const { data: products } = await client.products.list({
price_gte: 20,
price_lte: 100,
})
By Availability
const { data: products } = await client.products.list({
in_stock: true,
})
By Category
// Products in a specific category
const { data: products } = await client.categories.products.list('clothing/shirts', {
limit: 12,
})
// Or filter by category ID
const { data: products } = await client.products.list({
categories_id_eq: 'ctg_xxx',
})
const { data: products } = await client.products.list({
tags_cont: 'sale',
})
Sorting
// Sort by price (low to high)
const sorted = await client.products.list({
sort: 'price_low_to_high',
})
// Available sort options:
// price_low_to_high, price_high_to_low, newest, name_a_z, name_z_a
Product Filters (Faceted Search)
Get available filter options for building a faceted search UI. Returns option values, price ranges, and categories with counts:
const filters = await client.products.filters()
// {
// option_types: [{ name: "size", option_values: [{ name: "Small", count: 12 }, ...] }],
// price_range: { min: 9.99, max: 199.99 },
// categories: [{ id: "ctg_xxx", name: "Clothing", count: 45 }],
// }
// Scoped to a specific category
const categoryFilters = await client.products.filters({
category_id: 'ctg_xxx',
})
Filtering Other Resources
The Store API uses query parameters prefixed with q[] for filtering any resource collection. Common filter predicates:
Equality Predicates
| Predicate | Description | Example |
|---|
eq | Equals | q[status_eq]=active |
not_eq | Not equals | q[status_not_eq]=archived |
in | In array | q[id_in][]=1&q[id_in][]=2 |
String Predicates
| Predicate | Description | Example |
|---|
cont | Contains | q[name_cont]=shirt |
start | Starts with | q[name_start]=spree |
end | Ends with | q[email_end]=@example.com |
i_cont | Case-insensitive contains | q[name_i_cont]=SHIRT |
Comparison Predicates
| Predicate | Description | Example |
|---|
gt | Greater than | q[price_gt]=50 |
gteq | Greater than or equal | q[quantity_gteq]=10 |
lt | Less than | q[price_lt]=100 |
lteq | Less than or equal | q[created_at_lteq]=2025-12-31 |
NULL Predicates
| Predicate | Description | Example |
|---|
null | Is NULL | q[deleted_at_null]=true |
not_null | Is not NULL | q[published_at_not_null]=true |
present | Is not NULL and not empty | q[image_present]=true |
Only attributes explicitly allowed by each resource can be used for filtering. Attempting to filter on unsupported fields will be silently ignored.
All list endpoints support pagination:
const { data: products, meta } = await client.products.list({
page: 1,
limit: 24,
})
// meta.total_count => 150
// meta.total_pages => 7
See Querying for the full list of filtering, sorting, and pagination options.
- Products — Product catalog and listing
- Querying — API filtering, sorting, and pagination reference