Implementing an eCommerce Instant Search Autocomplete
Fast Simon JavaScript SDK allows developers to create a modern ecommerce instant search autocomplete includes Fast Simon advanced BigData AI, Merchandising, Personalization and more.
Using the Fast Simon JavaScript SDK, you can easily implement the following Instant Search capabilities following shoppers' prefix search term typing:
Product search results
Content search results
Popular Searches
Related Collections
Getting Instant Search Results
The instantSearch method allows you to get instant search results for a given shopper prefix-style query.
The instant search method utilizes the Fast Simon search functionality to execute the search operation based on the shopper's input. It communicates with the Fast Simon SDK to retrieve the corresponding products search results, collections, popular searches and content results.
In the search query the shopper defines what they are looking for, which is implemented using the query parameter. The callback function contains the relevant products, popular searches, collections and content results matching the shopper term.
window.FastSimonSDK.instantSearch({
query: searchTerm,
callback: (response) => {
console.log(response);
displayAutocomplete(response.payload, searchTerm);
}
});
The instantSearch request options:
Option | Type | Description |
---|---|---|
term | string (required) | Search query. |
callback | response void (required) | Callback to handler the search results. |
withAttributes | boolean Default: false | Determines whether to include attributes in the product response. Note: might increase latency, so use only if you need product tags or attributes. |
withCategories | boolean Default: false | Determines whether to include categories in return value. |
withProductTypes | boolean Default: false | Determines whether to include Product Types in the response. |
Rendering Instant Search Results per Shopper Query
Having a fast rendered search results is key to optimizing user experience and conversion optimization. Below is a short code snippet illustrating getting search results.
// Autocomplete Instant Search by Fast simon
const searchInput = document.getElementById('searchInput');
searchInput.addEventListener('input', function(event) {
const searchTerm = event.target.value;
// Use the following code for every keystroke shoppers perform in a searchbox.
window.FastSimonSDK.instantSearch({
query: searchTerm,
callback: (response) => {
console.log(response);
displayAutocomplete(response.payload, searchTerm);
}
});
console.log(searchTerm);
});
Implementation Examples
The full example of implementation you can find in the Fast Simon GitHub: Fast-Simon-Sample-JavaScript-SDK
HTML:
<input type="search" name="q" id="searchInput"></div>
Rendering Search Results in a Product Grid
Instant search results are typically attached to the input box in the site presenting shoppers products, collections, popular searches and content results. The product grid is designed to provide users with an overview of available products and data allowing them to browse and compare items quickly.
let linksContainer = document.createElement('div');
function displayAutocomplete(response, searchTerm) {
productList.innerHTML = '';
linksContainer.innerHTML = '';
turboLinkUrl = false;
// Add products to the modal
response.products.forEach(function(product) {
// Create a container for each product
const productContainer = document.createElement('li');
productContainer.classList.add('fs_product_ac');
// Add product information to the container
const productImage = document.createElement('img');
productImage.classList.add('fs_product_image_ac');
// product.t is an image URL
if (product.t) {
productImage.src = product.t;
} else {
productImage.src = 'https://acp-magento.appspot.com/images/missing.gif';
}
productContainer.appendChild(productImage);
if (product.l) { // title
const productName = document.createElement('h3');
productName.classList.add('fs_product_title_ac');
productName.textContent = product.l;
productContainer.appendChild(productName);
}
if (product.p && product.c) { // price
const productPrice = document.createElement('span');
productPrice.classList.add('fs_product_price_ac');
productPrice.textContent = `${product.p}`;
if (product.c == 'USD') {
productPrice.innerText = `$${productPrice.innerText}`;
}
productContainer.appendChild(productPrice);
}
if (product.p_c && product.p_c > 0 && product.c) { // Compare price
const productComparePrice = document.createElement('span');
productComparePrice.classList.add('fs_product_compare_price_ac');
productComparePrice.textContent = `${product.p_c}`;
if (product.c == 'USD') {
productComparePrice.innerText = `$${productComparePrice.innerText}`;
}
productContainer.appendChild(productComparePrice);
}
// Append the product container to the search results container
productList.appendChild(productContainer);
});
// Add content to the instant search dropdown
if (response.categories.length > 0 || response.popularSearches.length > 0 || response.turbolinks.length > 0) {
linksContainer.classList.add('fs_links_container');
productModal.querySelector('.modal-content').appendChild(linksContainer);
// Collections links
if (response.categories.length > 0) {
let collectionLinks = document.createElement('div');
collectionLinks.classList.add('fs_autocomplete_links', 'fs_collection_links');
let collectionLinksTitle = document.createElement('div');
collectionLinksTitle.classList.add('fs_autocomplete_links_title', 'fs_collection_links_title');
collectionLinksTitle.innerText = 'collections:';
collectionLinks.appendChild(collectionLinksTitle);
let counter = 0;
response.categories.forEach(category => {
if (counter < 3) {
let collectionLink = document.createElement('div');
collectionLink.classList.add('fs_autocomplete_link', 'fs_collection_link');
collectionLink.innerText = category.l;
collectionLink.setAttribute('id', category.id);
collectionLink.addEventListener('click', function(event) {
console.log('collection btn clicked');
event.preventDefault();
collectionID = collectionLink.getAttribute("id");
searchResultsContainer.classList.add('fs_collections');
if (searchResultsContainer.classList.contains('fs_search')) {
searchResultsContainer.classList.remove('fs_search');
}
clearFilters();
setUrlParam('collectionID', collectionID);
});
collectionLinks.appendChild(collectionLink);
counter++;
}
});
linksContainer.appendChild(collectionLinks);
}
// Popular searches links
if (response.popularSearches.length > 0) {
let popularSearchesLinks = document.createElement('div');
popularSearchesLinks.classList.add('fs_autocomplete_links', 'fs_popular_links');
let popularSearchesLinksTitle = document.createElement('div');
popularSearchesLinksTitle.classList.add('fs_autocomplete_links_title', 'fs_popular_links_title');
popularSearchesLinksTitle.innerText = 'popular searches:';
popularSearchesLinks.appendChild(popularSearchesLinksTitle);
let counter = 0;
response.popularSearches.forEach(popularSearch => {
if (counter < 3) {
let popularSearchLink = document.createElement('div');
popularSearchLink.classList.add('fs_autocomplete_link', 'fs_popularSearch_link');
popularSearchLink.innerText = popularSearch.l;
popularSearchLink.setAttribute('id', popularSearch.id);
popularSearchLink.addEventListener('click', function(event) {
console.log('popularSearchLink btn clicked');
event.preventDefault();
});
popularSearchesLinks.appendChild(popularSearchLink);
counter++;
}
});
linksContainer.appendChild(popularSearchesLinks);
}
// Turbolinks
if (response.turbolinks.length > 0) {
let turboLinks = document.createElement('div');
turboLinks.classList.add('fs_autocomplete_links', 'fs_turbo_links');
let turboLinksTitle = document.createElement('div');
turboLinksTitle.classList.add('fs_autocomplete_links_title', 'fs_turbo_links_title');
turboLinksTitle.innerText = 'turbolinks:';
turboLinks.appendChild(turboLinksTitle);
let counter = 0;
response.turbolinks.forEach(turbolink => {
if (counter < 3) {
let turboLink = document.createElement('a');
turboLink.classList.add('fs_autocomplete_link', 'fs_popularSearch_link');
turboLink.innerText = turbolink.l;
turboLink.href = turbolink.u;
turboLink.target = '_blank';
turboLinks.appendChild(turboLink);
// Save url for quick submit
if (turbolink.l.toLowerCase() == searchTerm.toLowerCase()) {
turboLinkUrl = turbolink.u;
}
counter++;
}
});
linksContainer.appendChild(turboLinks);
}
}
// Show the modal
if (response.products.length > 0 || response.turbolinks.length > 0) {
productModal.style.display = 'block';
} else {
productModal.style.display = 'none';
}
}
// Close the modal when the user clicks outside the modal
window.addEventListener('click', function(event) {
if (event.target !== productModal) {
productModal.style.display = 'none';
}
});
What data to include in the Instant Search Results
With Fast Simon SDK you can create a product grid that displays the following product properties:
interface Product {
c: string // currency
d: string // description
f: number // product merch stuff
id: string // product id
iso: boolean // is sold out
l: string // product title
p: string // price
p_c: string // comapre price
p_max: string
p_max_c: string
p_min: string
p_min_c: string
p_spl: number
review: number // review score
reviews_count: number // review count
s: string // sku (shopify foramt)
sku: string // sku
skus: string[] // skus
t: string // main image
t2: string // fallback image
u: string // url
v_c: number // varaint count
vra: Variant[] //product variants
vrc: object
att?: Attribute[] // product attribiutes
alt?: AlternativeProduct[] // alternative (sibiling) products
}
type Variant = [string, VariantData[]]
type VariantData = [string, string[]]
type Attribute = [string, AttributeData[]]
type AttributeData = [string, string[]]
export type AlternativeProduct = [AlternativeProductName, AlternativeProductURL, productID?]
type AlternativeProductName = string
type AlternativeProductURL = string
type productID = number
The product grid options:
Option | Type | Description |
---|---|---|
c | string | Product currency |
d | string | Product description |
f | number | Product merch stuff |
id | string | Product ID |
iso | boolean | Product is sold out or not |
l | string | Product main title |
p | string | Product price |
p_c | string | Product compare price in case of sale |
p_max | string | Variant max price range |
p_max_c | string | Compare variant max price range |
p_min | string | Variant min price range |
p_min_c | string | Compare variant min price range |
p_spl | number | · 1 if the product has variants · 0 in case of no variants |
p_spl_id | string | The ID of the product with variants |
review | number | Review number out of score rate between 0 – 100 |
review_count | number | The number of people reviewed the product |
s | string | SKU Shopify format codes that you can use internally to track your inventory and report on your sales. |
sku | string | SKU regular format |
skus | string | List of variant skus related to product. |
t | string | URL product main image |
t2 | string | URL fall back generic image presented only when the main URL is not accessible. |
u | string | Product location URL |
v_c | number | Variants count number |
vra | Variant[] | Product variants list |
vrc | object | Defined attributes for variant list. |
att? | Attribute[] | Product attributes such as tags custom defined per customer. |
alt? | AlternativeProduct[] | Alternative (sibling) products linked to the main product as viewed alternative selections. |
Reporting Shopper Activity
Every time a shopper selects an item from the autocomplete instant search Fast Simon needs to be reported on the activity. Fire the following events:
Event | Description |
---|---|
AutocompleteProductClicked | Shopper clicks on a specific product |
AutocompleteCategoryClicked | Shopper clicks on a specific collection |
AutocompletePopularClicked | Shoppers clicks on a particular popular search term |
Product Clicked in Autocomplete Event
window.FastSimonSDK.event({
eventName: window.FastSimonEventName.AutocompleteProductClicked,
data: {
query: term,
productID: "234213423"
}
)};
Event type AutocompleteProductClicked mandatory options:
Option | Value | Description |
---|---|---|
query | string | Determines the desired search query |
productID | string | Product ID chosen by the shopper |
Collection Clicked in Autocomplete Event
window.FastSimonSDK.event({
eventName: window.FastSimonEventName.AutocompleteCategoryClicked,
data: {
query: term,
collection: "89898989"
}
)};
Event type AutocompleteCategoryClicked mandatory options:
Option | Value | Description |
---|---|---|
query | string | Determines the desired search query |
collectionID | string | Product ID chosen by the shopper |
Popular Search Term Clicked in Autocomplete Event
window.FastSimonSDK.event({
eventName: window.FastSimonEventName.AutocompletePopularClicked,
data: {
query: "little",
term: "little black dress"
}
)};
Event type AutocompletePopularClicked mandatory options:
Option | Value | Description |
---|---|---|
query | string | Determines the desired search query |
term | string | Popular term selected by the shoppers |