Using the JavaScript Library
Search
For client-side/frontend integrations, Nosto's JavaScript library can be used to simplify the integration. It provides a programming interface to access the Search & Categories API.
For the most basic search the fields
parameter should be provided to specify what product/keyword fields should be returned. Both products
and keywords
can be used separately and together, depending on the use case. For all parameters, see the reference.
nostojs(api => {
api.search({
query: 'my search',
products: { fields: ["name"] },
keywords: { fields: ["keyword"] }
}).then(response => {
console.log(response);
});
});
Note: The first parameter of
api.search
generally corresponds to the graphql schema accepted by the search backend. The second parameter includes more frontend-specific logic like tracking or following redirects.
The second parameter of the api.search
function also accepts the following optional fields:
redirect
true
false
false
(Ignore redirects)
Automatically follow page redirects if instructed by the backend response
track
"autocomplete"
"category"
"serp"
undefined
undefined
(No tracking)
Track the search query as coming from the provided page type
isKeyword
true
false
false
(Not a keyword)
Indicates that the search is triggered by a keyword click in autocomplete
The function automatically loads session parameters required for personalization & segments in the background.
In order to request custom fields, add the entries "customFields.key"
and "customFields.value"
to the requested product fields. This changes the example above like this
// ...
products: { fields: ["name", "customFields.key", "customFields.value"] },
// ...
Search page
For a search page, the facets
parameter should generally be provided. In many cases, *
is sufficient as a wildcard to include all facets.
In order to automatically track search request to Nosto analytics, track
parameter should be provided with the correct page type.
isKeyword
should be set to true
if search is triggered by selecting a keyword suggested in the autocomplete.
nostojs(api => {
api.search({
query: 'my search',
products: {
facets: ['*'],
fields: ['name'],
size: 10
}
}, {
redirect: true,
track: 'serp',
isKeyword: true
}).then(response => {
console.log(response);
});
});
Redirects
The redirect
parameter, if set to true, causes the JS library to automatically follow any redirects returned by the backend. These are triggered by the merchant's configuration, redirecting certain user queries to specific pages. For example, query "summer" may get redirected to the "summer sale" collection.
The default redirection mechanism simply updates the window location:
window.location.href = response.redirect
Note: Do mix up
response.redirect
with the query'sredirect
property. The former contains the redirected target URL, while the latter is a boolean parameter on the query.
You may want to set query.redirect
to false
when this redirection mechanism is insufficient and you want to use another method, such as your framework's routing library. You may obtain the redirect target from response.redirect
field and act accordingly.
Autocomplete
track
should be enabled to automatically track searches to Nosto analytics.
nostojs(api => {
api.search({
query: 'my search',
products: {
fields: ['name'],
size: 10
},
keywords: {
fields: ['keyword'],
size: 5
}
}, {
track: 'autocomplete'
}).then(response => {
console.log(response);
});
});
Category page
For category pages in most cases the facets
parameter should be provided. Additionally categoryId (for Shopify) and categoryPath should be also provided.
Furthermore redirect
& track
should be enabled to automatically track searches to Nosto analytics & redirect if API returns a redirect request.
nostojs(api => {
api.search({
products: {
categoryId: '12345',
categoryPath: 'Pants',
fields: ['name'],
size: 10
}
}, {
track: 'category',
redirect: true
}).then(response => {
console.log(response);
});
});
Session parameters
For some of the search features to work properly, such as personalised results and segments, the search function needs to be able to access information about the user's session from the front-end.
To get all session data the following snippet can be used:
nostojs(api => {
api.getSearchSessionParams(options).then(response => {
console.log(response);
});
});
The results of this function should be passed to search query sessionParams parameter. In case search is called from backend, it should pass this data to backend (e.g. using form data).
The function accepts the following options:
maxWait
2000
Maximum execution time in MS
cacheRefreshInterval
60000
Maximum cache time
Analytics
Tracking search events to analytics can be divided into three parts: search
, search submit
, search product click
. These are user behaviours that should be tracked:
search submit (
type = serp
)faceting, paginating, sorting (
type = serp
) or (type = category
)autocomplete input (
type = autocomplete
)search results product click (
type = serp
), (type = autocomplete
) or (type = category
)autocomplete keyword click (
type = autocomplete
)category merchandising results (
type = category
)
JS API library provides tracking helpers for all of these cases.
Error Handling
On errors from api.search
calls the error object contains a status field that has the HTTP response status which can be used to determine the cause of the error in addition to the error message. The ranges of the status codes used for errors are 400-499 and 500-599. For details on these error codes, go to HTTP response status codes
Search
User actions that lead to search results should be tracked with api.recordSearch()
after search request is done:
search submit (
type = serp
) - user submits search query in autocomplete component and is landed to SERPfaceting, paginating, sorting (
type = serp
) or (type = category
) - user adjusts current search results by filtering (e.g. brand), selecting search page, sorting resultsautocomplete input (
type = autocomplete
) - user sees partial results while typing in search inputcategory merchandising results (
type = category
) - user sees specific category results when category is selected (category merchandising must be implemented)
You don't need to execute api.recordSearch()
if you call api.search(query, { track: 'serp'|'autocomplete'|'category'})
function from JS API, becauseapi.search()
already calls api.recordSearch()
when track
option is provided.
nostojs(async (api) => {
const searchRequest = {
query: "shoes",
products: {
sort: [{ field: "price", order: "asc" }],
filter: [{ "field": "brand", "value": "Nike" }]
}
}
const response = await sendGraphQlRequest(searchRequest)
const searchResult = response.data.search
api.recordSearch(
type,
searchRequest,
searchResult,
options
)
})
type
Search type: serp
, autocomplete
, category
request
result
options (optional)
Record search options. Currently is accepts:
isKeyword: boolean
- should be set when keyword in autocomplete is clicked (search is submitted via keyword)
Example:
api.recordSearch(
"serp",
{
query: "shoes",
products: {
sort: [{ field: "price", order: "asc" }],
filter: [{ "field": "brand", "value": "Nike" }]
}
},
{
products: {
hits: [{ productId: "123" }, { productId: "124" }],
fuzzy: true,
total: 2,
size: 2,
from: 0
}
},
{
isKeyword: false
}
)
Keyword click tracking
Example:
api.recordSearch(
'autocomplete',
searchRequest,
searchResult,
{
isKeyword: true
}
)
Category results tracking
Example:
api.recordSearch(
'category',
{
products: {
categoryId: "123456",
categoryPath: "Pants",
sort: [{ field: "price", order: "asc" }]
size: 24,
from: 0,
}
},
{
products: {
categoryId: "123456",
categoryPath: "Pants",
hits: [{ productId: "123" }, { productId: "124" }],
fuzzy: true,
total: 18,
size: 24,
from: 0
}
},
{
isKeyword: false
}
)
The tracking metadata is primarily taken from the third parameter. The full request and full result objects must be provided in the api.recordSearch
call instead of partials.
Search form submit
Search queries are categorised into two groups: organic and non-organic searches.
In order to mark a search query as an organic search you need to call api.recordSearchSubmit(query: string)
. You should call it on search input submit only, before search request is sent.
nostojs(api => {
const query = 'shoes'
api.recordSearchSubmit(query)
})
Search product click
Product clicks should be tracked in autocomplete component, SERP, category page with api.recordSearchClick()
by providing component (type), where click occurred, and clicked product data:
nostojs(api => {
api.recordSearchClick(type, hit)
})
type
Search type: serp
, autocomplete
, category
hit
Object containing productId
and url
, collected from clicked product
Example:
api.recordSearchClick(
"autocomplete",
{ productId: "123", url: "https://myshop.com/product123" }
)
Search add to cart additions
When shopping cart additions happen directly as part of the search, category or autocomplete results without a navigation to the product page, the api.recordSearchAddToCart()
method should be called with the component (type), where addition occurred and the product data:
nostojs(api => {
api.recordSearchAddToCart(type, hit)
})
type
Search type: serp
, autocomplete
, category
hit
Object containing productId
and url
, collected from product
Example:
api.recordSearchAddToCart(
"autocomplete",
{ productId: "123", url: "https://myshop.com/product123" }
)
⚠️ Event Tracking Requirements ⚠️
When tracking events, adherence to the following criteria is essential for capturing detailed and valid data:
query
parameter:The
query
string is an essential component for event tracking.If present, include
products.sort
to track sorting behavior.If applicable, incorporate
products.filter
.
searchResults
parameter:products.hits
array containing objects with aproductId
is mandatory.products.total
number to identify if the search has results.For accurate pagination tracking,
products.from
andproduct.size
must be included.For identifying if the request was autocorrected include
products.fuzzy
.For category requests, either
products.categoryId
orproducts.categoryPath
is mandatory.
💡 Tip: In case of API integration, use this example GraphQL partial query to integrate with the API and retrieve the necessary response data for precise event tracking.
query {
search(
accountId: "YOUR_ACCOUNT_ID"
query: "green"
products: { size: 10, from: 10 }
) {
products {
hits {
productId
}
total
size
from
fuzzy
categoryId
categoryPath
}
}
}
🚩 Search Form Submit
Bear in mind that search queries are split between organic and non-organic searches. To classify a search as organic, it is crucial to invoke api.recordSearchSubmit()
upon the search input submission, before the actual search request is dispatched. This step is pivotal in ensuring the seamless tracking of organic searches through to the SERP.
🔍 Accurate Click Tracking
Tracking product clicks is fundamental for understanding user interaction. Use api.recordSearchClick()
to monitor this actions correctly, specifying the type
and relevant hit data.
In case of an SPA based integration the api.recordSearchClick
calls should be complemented with Session API or api.createRecommendationRequest()
usage to couple the search analytics events to generic Nosto events for accurate attribution.
Last updated
Was this helpful?