As with all front end customisations, adding a debounce delay in Shopify requires the use of Custom Hooks. The hook required for this will be beforeAutocompleteOptions, more about which can be found in our docs - https://www.algolia.com/doc/integration/shopify/building-search-ui/frontend-custom-events/?client=ruby#beforeautocompleteoptions
This hook will allow you to perform actions prior to the autocomplete query being sent. In this case, the debounce function can be used to ensure that there is a delay between user input and a request being sent to Algolia.
The following code will achieve this outcome:
document.addEventListener("algolia.hooks.initialize", function () {
algoliaShopify.hooks.registerHook(
"beforeAutocompleteOptions",
function (options) {
function debouncePromise(func, time) {
let timerId = undefined;
return function debounced(...args) {
console.log("debounced args", ...args);
if (timerId) {
clearTimeout(timerId);
}
return new Promise((resolve) => {
timerId = setTimeout(() => resolve(func, ...args), time);
});
};
}
const debounced = debouncePromise(
(items) => Promise.resolve(items),
1000
);
options.getSources = function ({ query, setContext }) {
return [
{
sourceId: "products",
getItems() {
return debounced(
algoliaShopify.externals.getAlgoliaResults({
searchClient: algoliaShopify.searchClient,
queries: [
{
indexName: `${algoliaShopify.config.index_prefix}products`,
query,
},
],
})
);
},
templates: {
noResults() {
return null;
},
item({ item }) {
return `${item.title}`;
},
},
},
];
};
return options;
}
);
});
document.addEventListener("algolia.hooks.initialize", function () {
algoliaShopify.hooks.registerHook(
"beforeAutocompleteOptions",
function (options) {
function debouncePromise(func, time) {
let timerId = undefined;return function debounced(...args) {
console.log("debounced args", ...args);
if (timerId) {
clearTimeout(timerId);
}
return new Promise((resolve) => {
timerId = setTimeout(() => resolve(func, ...args), time);
});
};
}
const debounced = debouncePromise(
(items) => Promise.resolve(items),
10000
);
options.getSources = function ({ query, setContext }) {
return debounced([
{
sourceId: "products",
getItems() {
return getAlgoliaResults({
searchClient: algoliaShopify.searchClient,
queries: [
{
indexName: `${algoliaShopify.config.index_prefix}products`,
query,
},
],
});
},
},
]);
};
return options;
}
);
});
document.addEventListener("algolia.hooks.initialize", function () {
algoliaShopify.hooks.registerHook(
"beforeAutocompleteOptions",
function (options) {
function debouncePromise(func, time) {
let timerId = undefined;return function debounced(...args) {
console.log("debounced args", ...args);
if (timerId) {
clearTimeout(timerId);
}
return new Promise((resolve) => {
timerId = setTimeout(() => resolve(func, ...args), time);
});
};
}
const debounced = debouncePromise(
(items) => Promise.resolve(items),
10000
);
options.getSources = function ({ query, setContext }) {
return debounced([
{
sourceId: "products",
getItems() {
return getAlgoliaResults({
searchClient: algoliaShopify.searchClient,
queries: [
{
indexName: `${algoliaShopify.config.index_prefix}products`,
query,
},
],
});
},
},
]);
};
return options;
}
);
});
document.addEventListener("algolia.hooks.initialize", function () {
algoliaShopify.hooks.registerHook(
"beforeAutocompleteOptions",
function (options) {
function debouncePromise(func, time) {
let timerId = undefined;return function debounced(...args) {
console.log("debounced args", ...args);
if (timerId) {
clearTimeout(timerId);
}
return new Promise((resolve) => {
timerId = setTimeout(() => resolve(func, ...args), time);
});
};
}
const debounced = debouncePromise(
(items) => Promise.resolve(items),
10000
);
options.getSources = function ({ query, setContext }) {
return debounced([
{
sourceId: "products",
getItems() {
return getAlgoliaResults({
searchClient: algoliaShopify.searchClient,
queries: [
{
indexName: `${algoliaShopify.config.index_prefix}products`,
query,
},
],
});
},
},
]);
};
return options;
}
);
});
document.addEventListener("algolia.hooks.initialize", function () {
algoliaShopify.hooks.registerHook(
"beforeAutocompleteOptions",
function (options) {
function debouncePromise(func, time) {
let timerId = undefined;return function debounced(...args) {
console.log("debounced args", ...args);
if (timerId) {
clearTimeout(timerId);
}
return new Promise((resolve) => {
timerId = setTimeout(() => resolve(func, ...args), time);
});
};
}
const debounced = debouncePromise(
(items) => Promise.resolve(items),
10000
);
options.getSources = function ({ query, setContext }) {
return debounced([
{
sourceId: "products",
getItems() {
return getAlgoliaResults({
searchClient: algoliaShopify.searchClient,
queries: [
{
indexName: `${algoliaShopify.config.index_prefix}products`,
query,
},
],
});
},
},
]);
};
return options;
}
);
});
document.addEventListener("algolia.hooks.initialize", function () {
algoliaShopify.hooks.registerHook(
"beforeAutocompleteOptions",
function (options) {
function debouncePromise(func, time) {
let timerId = undefined;return function debounced(...args) {
console.log("debounced args", ...args);
if (timerId) {
clearTimeout(timerId);
}
return new Promise((resolve) => {
timerId = setTimeout(() => resolve(func, ...args), time);
});
};
}
const debounced = debouncePromise(
(items) => Promise.resolve(items),
10000
);
options.getSources = function ({ query, setContext }) {
return debounced([
{
sourceId: "products",
getItems() {
return getAlgoliaResults({
searchClient: algoliaShopify.searchClient,
queries: [
{
indexName: `${algoliaShopify.config.index_prefix}products`,
query,
},
],
});
},
},
]);
};
return options;
}
);
});
document.addEventListener("algolia.hooks.initialize", function () {
algoliaShopify.hooks.registerHook(
"beforeAutocompleteOptions",
function (options) {
function debouncePromise(func, time) {
let timerId = undefined;return function debounced(...args) {
console.log("debounced args", ...args);
if (timerId) {
clearTimeout(timerId);
}
return new Promise((resolve) => {
timerId = setTimeout(() => resolve(func, ...args), time);
});
};
}
const debounced = debouncePromise(
(items) => Promise.resolve(items),
10000
);
options.getSources = function ({ query, setContext }) {
return debounced([
{
sourceId: "products",
getItems() {
return getAlgoliaResults({
searchClient: algoliaShopify.searchClient,
queries: [
{
indexName: `${algoliaShopify.config.index_prefix}products`,
query,
},
],
});
},
},
]);
};
return options;
}
);
});
document.addEventListener("algolia.hooks.initialize", function () {
algoliaShopify.hooks.registerHook(
"beforeAutocompleteOptions",
function (options) {
function debouncePromise(func, time) {
let timerId = undefined;return function debounced(...args) {
console.log("debounced args", ...args);
if (timerId) {
clearTimeout(timerId);
}
return new Promise((resolve) => {
timerId = setTimeout(() => resolve(func, ...args), time);
});
};
}
const debounced = debouncePromise(
(items) => Promise.resolve(items),
10000
);
options.getSources = function ({ query, setContext }) {
return debounced([
{
sourceId: "products",
getItems() {
return getAlgoliaResults({
searchClient: algoliaShopify.searchClient,
queries: [
{
indexName: `${algoliaShopify.config.index_prefix}products`,
query,
},
],
});
},
},
]);
};
return options;
}
);
});
document.addEventListener("algolia.hooks.initialize", function () {
algoliaShopify.hooks.registerHook(
"beforeAutocompleteOptions",
function (options) {
function debouncePromise(func, time) {
let timerId = undefined;return function debounced(...args) {
console.log("debounced args", ...args);
if (timerId) {
clearTimeout(timerId);
}
return new Promise((resolve) => {
timerId = setTimeout(() => resolve(func, ...args), time);
});
};
}
const debounced = debouncePromise(
(items) => Promise.resolve(items),
10000
);
options.getSources = function ({ query, setContext }) {
return debounced([
{
sourceId: "products",
getItems() {
return getAlgoliaResults({
searchClient: algoliaShopify.searchClient,
queries: [
{
indexName: `${algoliaShopify.config.index_prefix}products`,
query,
},
],
});
},
},
]);
};
return options;
}
);
});
document.addEventListener("algolia.hooks.initialize", function () {
algoliaShopify.hooks.registerHook(
"beforeAutocompleteOptions",
function (options) {
function debouncePromise(func, time) {
let timerId = undefined;return function debounced(...args) {
console.log("debounced args", ...args);
if (timerId) {
clearTimeout(timerId);
}
return new Promise((resolve) => {
timerId = setTimeout(() => resolve(func, ...args), time);
});
};
}
const debounced = debouncePromise(
(items) => Promise.resolve(items),
10000
);
options.getSources = function ({ query, setContext }) {
return debounced([
{
sourceId: "products",
getItems() {
return getAlgoliaResults({
searchClient: algoliaShopify.searchClient,
queries: [
{
indexName: `${algoliaShopify.config.index_prefix}products`,
query,
},
],
});
},
},
]);
};
return options;
}
);
});
document.addEventListener("algolia.hooks.initialize", function () {
algoliaShopify.hooks.registerHook(
"beforeAutocompleteOptions",
function (options) {
function debouncePromise(func, time) {
let timerId = undefined;return function debounced(...args) {
console.log("debounced args", ...args);
if (timerId) {
clearTimeout(timerId);
}
return new Promise((resolve) => {
timerId = setTimeout(() => resolve(func, ...args), time);
});
};
}
const debounced = debouncePromise(
(items) => Promise.resolve(items),
10000
);
options.getSources = function ({ query, setContext }) {
return debounced([
{
sourceId: "products",
getItems() {
return getAlgoliaResults({
searchClient: algoliaShopify.searchClient,
queries: [
{
indexName: `${algoliaShopify.config.index_prefix}products`,
query,
},
],
});
},
},
]);
};
return options;
}
);
});
document.addEventListener("algolia.hooks.initialize", function () {
algoliaShopify.hooks.registerHook(
"beforeAutocompleteOptions",
function (options) {
function debouncePromise(func, time) {
let timerId = undefined;return function debounced(...args) {
console.log("debounced args", ...args);
if (timerId) {
clearTimeout(timerId);
}
return new Promise((resolve) => {
timerId = setTimeout(() => resolve(func, ...args), time);
});
};
}
const debounced = debouncePromise(
(items) => Promise.resolve(items),
10000
);
options.getSources = function ({ query, setContext }) {
return debounced([
{
sourceId: "products",
getItems() {
return getAlgoliaResults({
searchClient: algoliaShopify.searchClient,
queries: [
{
indexName: `${algoliaShopify.config.index_prefix}products`,
query,
},
],
});
},
},
]);
};
return options;
}
);
});
document.addEventListener("algolia.hooks.initialize", function () {
algoliaShopify.hooks.registerHook(
"beforeAutocompleteOptions",
function (options) {
function debouncePromise(func, time) {
let timerId = undefined;return function debounced(...args) {
console.log("debounced args", ...args);
if (timerId) {
clearTimeout(timerId);
}
return new Promise((resolve) => {
timerId = setTimeout(() => resolve(func, ...args), time);
});
};
}
const debounced = debouncePromise(
(items) => Promise.resolve(items),
10000
);
options.getSources = function ({ query, setContext }) {
return debounced([
{
sourceId: "products",
getItems() {
return getAlgoliaResults({
searchClient: algoliaShopify.searchClient,
queries: [
{
indexName: `${algoliaShopify.config.index_prefix}products`,
query,
},
],
});
},
},
]);
};
return options;
}
);
});
document.addEventListener("algolia.hooks.initialize", function () {
algoliaShopify.hooks.registerHook(
"beforeAutocompleteOptions",
function (options) {
function debouncePromise(func, time) {
let timerId = undefined;return function debounced(...args) {
console.log("debounced args", ...args);
if (timerId) {
clearTimeout(timerId);
}
return new Promise((resolve) => {
timerId = setTimeout(() => resolve(func, ...args), time);
});
};
}
const debounced = debouncePromise(
(items) => Promise.resolve(items),
10000
);
options.getSources = function ({ query, setContext }) {
return debounced([
{
sourceId: "products",
getItems() {
return getAlgoliaResults({
searchClient: algoliaShopify.searchClient,
queries: [
{
indexName: `${algoliaShopify.config.index_prefix}products`,
query,
},
],
});
},
},
]);
};
return options;
}
);
});
document.addEventListener("algolia.hooks.initialize", function () {
algoliaShopify.hooks.registerHook(
"beforeAutocompleteOptions",
function (options) {
function debouncePromise(func, time) {
let timerId = undefined;return function debounced(...args) {
console.log("debounced args", ...args);
if (timerId) {
clearTimeout(timerId);
}
return new Promise((resolve) => {
timerId = setTimeout(() => resolve(func, ...args), time);
});
};
}
const debounced = debouncePromise(
(items) => Promise.resolve(items),
10000
);
options.getSources = function ({ query, setContext }) {
return debounced([
{
sourceId: "products",
getItems() {
return getAlgoliaResults({
searchClient: algoliaShopify.searchClient,
queries: [
{
indexName: `${algoliaShopify.config.index_prefix}products`,
query,
},
],
});
},
},
]);
};
return options;
}
);
});