In this walkthrough, we’ll be examining how we built the commerce app’s search and category pages. We will go through:
Searching For Products.
Using the Commerce SDK to handle search requests
Handling type-ahead suggestion requests
Prior to loading content specific to searching for products we need to know, certain information prior, Specifically:
Resolve the tenant and application
To prepare for those requests, there are only two things required. First we need to resolve the Application, see Tenant & Application Walkthrough. Second we need to build the search parameters with the query, filters, and sort for the request.
searchProducts
METHOD |
URL |
SDK |
|
Catalog Search |
GET |
/api/catalog-browse |
searchProducts(searchParams, options) |
Tip
|
Details can be found in the Catalog Search OpenAPI Documentation |
There is a single required parameter of the type SearchParams, which can contain important params such as query
. The result will return a SearchResponse<Product>
which has a property called content
that contains the result of your query.
import { ClientOptions } from '@broadleaf/commerce-core';
import { BrowseClient } from '@broadleaf/commerce-browse';
async function searchFor(searchParams: SearchParams, options: ClientOptions) {
const client = new BrowseClient(options);
// EXAMPLE of SearchParams:
// const searchParams = { query: "Green Ghost" };
// BrowseClientCallOptions is OPTIONAL
// BrowseClientCallOptions extends ClientCallOptions
const priceContext: PriceContext = {
locale: "en-US",
currency: "USD"
};
const browserCallOptions: BrowseClientCallOptions = { priceContext }
return client.searchProducts(searchParams, browserCallOptions);
}
This returns a SearchResponse<Product>
, seen below. Note that the resulting Product
results will be in content
while the other information is for pagination, sorting, and filtering.
{
"content": [
{
"id": "product1",
"sku": "HS-GG-20",
...
}
],
"last": true,
"pageable": {
"sort": {
"sorted": true,
"unsorted": false,
"empty": false
},
"pageSize": 50,
"pageNumber": 0,
"paged": true,
"unpaged": false,
"offset": 0
},
"sort": {
"sorted": true,
"unsorted": false,
"empty": false
},
"facets": [ ... ],
"totalElements": 5,
"empty": false,
"number": 0,
"numberOfElements": 5,
"size": 50,
"correctedQuery": false,
"totalPages": 1,
"sorts": [
{
"sortOption": {
"label": "Name",
"name": "name",
"displayOrder": 1
},
"active": true,
"descending": false
},
],
"first": true
}
SearchParams
contains optional properties to query products from a catalog
property |
type |
description |
required |
|
filters |
Array<Filter> |
The rule filters to apply. |
optional |
query |
string |
The query to search for. |
optional |
ruleFilters.rule |
string |
The rule filters to apply. |
optional |
ruleFilters.overrideLocale |
string |
This locale would override whatever context the current locale is in when evaluating the rule values against the Solr document fields. This is useful since the rule is a simple string without translations. |
optional |
categoryProductMembershipFilters.rule |
string |
The rule-based RSQL filters used to check if a related product is a member of the specified category. Only applies when the category’s product membership type is |
optional |
categoryProductMembershipFilters.overrideLocale |
string |
This locale would override whatever context the current locale is in when evaluating the rule values against the Solr document fields. This is useful since the rule is a simple string without translations. |
optional |
sort |
SearchParams
contains the ability to apply filters that take an array of Filter
objects. Below is an example of a price filter.
async function searchFor(searchParams: SearchParams, options: ClientOptions) {
const client = new BrowseClient(options);
const query = "Hot Sauce" ;
const filters: Array<Filter> = [
{
name: 'price',
ranges: [{ minValue: '0', maxValue: '15' }]
}
];
const searchParams = { query, filters };
return await client.searchProducts(searchParams);
}
Filter contains properties to filter product results products from a catalog search
property |
type |
description |
required |
|
name |
string |
The name of the filter. |
required |
values |
Array<string> |
The values associated to the filter. |
optional |
ranges |
Array<FacetRange> |
A FacetRange
contains optional properties to create a range filter
property |
type |
description |
required |
|
label |
string |
The label for the facet range. |
optional |
displayOrder |
number |
The values associated to the filter. |
optional |
minValue |
string |
The minimum value of the range. |
optional |
maxValue |
string |
The maximum value for the range. |
Another key feature is the ability to get type-ahead suggestions from the SDK. These are used to provided autocomplete suggestions as well as specific products or categories that may match what the user is looking for and can save them form having to look through a search results page.
searchSuggestionsRequest
METHOD |
URL |
SDK |
|
Catalog Search Suggest |
GET |
/search/catalog/suggest |
searchSuggestionsRequest(searchSuggestionsRequest, options) |
Tip
|
Details can be found in the Catalog Search Suggest OpenAPI Documentation |
There is a single required parameter of the type SearchSuggestionsRequest
, that is described below, which will return the suggestions as a SearchSuggestionsResponse
object.
import { ClientOptions } from '@broadleaf/commerce-core';
import { BrowseClient } from '@broadleaf/commerce-browse';
async function searchFor(searchSuggestionsRequest: SearchSuggestionsRequest, options: ClientOptions) {
const client = new BrowseClient(options);
// EXAMPLE of SearchSuggestionsRequest:
// const searchSuggestionsRequest = { query: "Green Ghost" };
return await client.searchSuggestions(searchSuggestionsRequest);
}
This is the SearchSuggestionsResponse
object that is returned by searchSuggestions
.
{
"suggestions": {
"categories": [
{
"categoryNames": "Hot Sauces",
"numResults": 1
},
...
],
"products": [ ... ]
},
"keyWords": [
{
"highlightedSuggestion": "<strong>Greeen</strong> Ghost",
"suggestion": "Greeen Ghost"
}
]
}