Skip to main content

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:

OptionTypeDescription
termstring (required)Search query.
callbackresponse void (required)Callback to handler the search results.
withAttributesboolean Default: falseDetermines whether to include attributes in the product response. Note: might increase latency, so use only if you need product tags or attributes.
withCategoriesboolean Default: falseDetermines whether to include categories in return value.
withProductTypesboolean Default: falseDetermines 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:

OptionTypeDescription
cstringProduct currency
dstringProduct description
fnumberProduct merch stuff
idstringProduct ID
isobooleanProduct is sold out or not
lstringProduct main title
pstringProduct price
p_cstringProduct compare price in case of sale
p_maxstringVariant max price range
p_max_cstringCompare variant max price range
p_minstringVariant min price range
p_min_cstringCompare variant min price range
p_splnumber· 1 if the product has variants · 0 in case of no variants
p_spl_idstringThe ID of the product with variants
reviewnumberReview number out of score rate between 0 – 100
review_countnumberThe number of people reviewed the product
sstringSKU Shopify format codes that you can use internally to track your inventory and report on your sales.
skustringSKU regular format
skusstringList of variant skus related to product.
tstringURL product main image
t2stringURL fall back generic image presented only when the main URL is not accessible.
ustringProduct location URL
v_cnumberVariants count number
vraVariant[]Product variants list
vrcobjectDefined 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:

EventDescription
AutocompleteProductClickedShopper clicks on a specific product
AutocompleteCategoryClickedShopper clicks on a specific collection
AutocompletePopularClickedShoppers 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:

OptionValueDescription
querystringDetermines the desired search query
productIDstringProduct 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:

OptionValueDescription
querystringDetermines the desired search query
collectionIDstringProduct ID chosen by the shopper
window.FastSimonSDK.event({
eventName: window.FastSimonEventName.AutocompletePopularClicked,
data: {
query: "little",
term: "little black dress"
}
)};

Event type AutocompletePopularClicked mandatory options:

OptionValueDescription
querystringDetermines the desired search query
termstringPopular term selected by the shoppers