Skip to main content
As of December 31, 2023, Shopify no longer allows apps to modify theme code. To integrate Autocomplete and InstantSearch, use the Algolia AI Search & Discovery app’s App Embed and App Blocks. To get started, see Quickstart and Algolia configuration.
Hooks are functions that run at specific points of the Algolia app’s lifecycle. They let you register custom functions that change certain aspects of the Autocomplete and InstantSearch integrations. To listen to global events without passing or changing data, see Global events. To view the available hooks, go to your Shopify store and enter window.algoliaShopify.hooks.allowedHooks into the developer tools’ console of your browser. An example of allowed hooks

Deprecated hooks

The following custom hooks are deprecated since March 31, 2025.

Add custom hooks

To use these hooks, add a new JavaScript file to your theme.

Create the file

  1. Go to your theme list, select the theme you want to customize, and click the three dots next to the theme to reveal the menu. Edit the theme code
  2. Select Edit code.
  3. From the Assets section in the left-hand menu, click Add a new asset. Add a new asset file
  4. Select the Create a blank file tab and then select js from the drop-down menu. Add a new JavaScript asset file
  5. Enter a filename, for example, algolia_custom_hooks and click Done.

Include the file in your theme

The next step is to include this new JavaScript file in the theme:
  1. In the Edit code tab, open the theme.liquid file.
  2. Scroll to the bottom of the theme.liquid file and add the following just before the </body> tag. Replace NEW_FILE with the filename of the JavaScript file with your custom hook:
    HTML
        <script src="{{ 'NEW_FILE.js' | asset_url }}" defer="defer"></script>
      </body>
    </html>
    
  3. Save the file.

Use custom hooks

To register a function to a hook, open the specific hooks JavaScript file, add an event listener to the algolia.hooks.initialize event, and call the algoliaShopify.hooks.registerHook function. For example:
JavaScript
document.addEventListener('algolia.hooks.initialize', function() {
  algoliaShopify.hooks.registerHook('beforeAutocompleteOptions', function (options) { /* */ });
});
The return values of the function you register with the hook must match the expected return type, indicated by the hook’s name.
Hook name ends withExpected return type
OptionsObject
TemplateTagged template literal
ArrayArray of strings or objects
StringString
NumberNumber
ActionFunction

Autocomplete hooks

Hooks in this section change the behavior of the autocomplete menu.

beforeAutocompleteAsyncFunction

This hook waits for any asynchronous function, such as an external API request, to complete before continuing. It runs before any autocomplete parameters are set. You can include multiple await statements within this hook to handle several asynchronous operations sequentially. Example:
JavaScript
const sleep = (ms, hookName) => new Promise(resolve => {
  console.log("sleeping for ", ms, hookName);
  setTimeout(resolve, ms);
});

document.addEventListener('algolia.hooks.initialize', function() {
  algoliaShopify.hooks.registerHook('beforeAutocompleteAsyncFunction', async function() {
    console.log("----------- beforeAutocompleteAsyncFunction started ----------------")
    await sleep(1000, 'beforeAutocompleteAsyncFunction');
  });
});

beforeAutocompleteOptions

Sets parameters for the autocomplete menu. Example:
JavaScript
document.addEventListener('algolia.hooks.initialize', function() {
  algoliaShopify.hooks.registerHook('beforeAutocompleteOptions', function(options) {
    // Change the placeholder text of the autocomplete menu
    options.placeholder = "Search Our Products";
    return options;
  });
});

beforeAutocompleteFiltersString

Adds filter parameter to the autocomplete menu. Example:
JavaScript
document.addEventListener('algolia.hooks.initialize', function() {
  algoliaShopify.hooks.registerHook('beforeAutocompleteFiltersString', function(_defaultFilter) {
    // Don't return the default filter and return a custom filter
    return 'price > 17';
  });
});

beforeAutocompleteRedirectUrlOptions

Changes the default parameters of the createRedirectUrlPlugin function. Example:
JavaScript
document.addEventListener('algolia.hooks.initialize', function() {
  algoliaShopify.hooks.registerHook('beforeAutocompleteRedirectUrlOptions', function(options) {
    // Change the default template for rendering redirect items 
    return {
      templates: {
        item({ html, state }) {
          return html`<a className="myCustomClass">${state.query}</a>`;
        },
      },
    };
  });
});

beforeAutocompleteMainTemplate

Changes the HTML template that renders the Autocomplete panel. You can use this to render an Autocomplete multi-panel layout. The elements object has the following properties:
  • querySuggestionsPlugin
  • collections
  • articles
  • pages
  • redirectUrlPlugin
  • products
Example:
JavaScript
document.addEventListener('algolia.hooks.initialize', function() {
  algoliaShopify.hooks.registerHook('beforeAutocompleteMainTemplate', function(_defaultTemplate, templateOptions, elements, displaySuggestions) {
    const { html } = templateOptions;
    // Don't return the default template and return a custom two-column layout instead
    return html`
      <div class="aa-PanelLayout aa-Panel--scrollable">
        <div class="aa-PanelSections">
          <div class="aa-PanelSection--left">
            ${displaySuggestions &&
              html`
                <div class="aa-SourceHeader">
                  <span class="aa-SourceHeaderTitle"
                    >${algoliaShopify.translations.suggestions}</span
                  >
                  <div class="aa-SourceHeaderLine" />
                </div>
                ${elements.querySuggestionsPlugin}
              `}
            ${elements.collections} ${elements.articles} ${elements.pages}
            ${elements.redirectUrlPlugin}
          </div>
          <div class="aa-PanelSection--right">
            ${elements.products}
          </div>
        </div>
      </div>
    `;
  });
});

beforeAutocompleteMainProductsTemplate

Renders the product section in the autocomplete menu. Example:
JavaScript
document.addEventListener('algolia.hooks.initialize', function() {
  algoliaShopify.hooks.registerHook('beforeAutocompleteMainProductsTemplate', function(_defaultTemplate, templateOptions, elements) {
    const { html } = templateOptions;
    return html`
      <div class="aa-PanelLayout aa-Panel--scrollable">
        <div class="aa-PanelSection">
          ${elements.products}
        </div>
      </div>
    `;
  });
});

beforeAutocompleteNoResultsTemplate

Renders when there are no search results. Example:
JavaScript
document.addEventListener('algolia.hooks.initialize', function() {
  algoliaShopify.hooks.registerHook('beforeAutocompleteNoResultsTemplate', function(_defaultTemplate, templateOptions) {
    const { html, state } = templateOptions;
    return html`
      <div class="aa-PanelLayout aa-Panel--scrollable">
        <p class="aa-NoResultsHeader">
          ${algoliaShopify.translation_helpers.no_result_for(state.query)}
        </p>
        <a class="aa-NoResultsLink" href="${window.Shopify.routes.root}search?q=">
          ${algoliaShopify.translations.allProducts}
        </a>
      </div>
    `;
  });
});

beforeAutocompleteHeaderTemplate

Renders a header section at the top of the autocomplete results panel. Example:
JavaScript
document.addEventListener('algolia.hooks.initialize', function() {
  algoliaShopify.hooks.registerHook('beforeAutocompleteHeaderTemplate', function(_defaultTemplate, templateOptions, resource) {
    const { html, state } = templateOptions;
    return html`
      <div class="aa-SourceHeader">
        <span class="aa-SourceHeaderTitle">
          ${algoliaShopify.translation_helpers.render_title(
            resource,
            state.query
          )}
        </span>
        <div class="aa-SourceHeaderLine" />
      </div>
    `;
  });
});

beforeAutocompleteFooterTemplate

Renders a footer section at the bottom of the autocomplete results panel. To render a footer, select the Show See All products option in the Autocomplete Search options in your store’s admin. Example:
JavaScript
document.addEventListener('algolia.hooks.initialize', function() {
  algoliaShopify.hooks.registerHook('beforeAutocompleteFooterTemplate', function(_defaultTemplate, templateOptions) {
    const { html, state } = templateOptions;
    return html`
      <div class="aa-footer">
        <a
          class="aa-SeeAllBtn"
          href="${window.Shopify.routes.root}search?q=${state.query}"
        >
          ${algoliaShopify.translations.allProducts}
          (${algoliaShopify.helpers.formatNumber(state.context.nbProducts)})
        </a>
      </div>
    `;
  });
});

beforeAutocompleteProductTemplate

Template for rendering each product hit in the autocomplete results. If you are using this template, ensure you also call trackSearchAttribution(item) to properly handle events. Example:
JavaScript
document.addEventListener("algolia.hooks.initialize", function () {
  algoliaShopify.hooks.registerHook(
    "beforeAutocompleteProductTemplate",
    function (_defaultTemplate, templateOptions, distinct, itemLink, trackSearchAttribution) {
      // Modify default options, then return them
      const { html, item, components } = templateOptions;
      return html`
    <a
      href="${itemLink}"
      class="aa-ItemLink aa-ProductItem"
      onClick="${() => trackSearchAttribution(item)}"
    >
      <div class="aa-ItemContent">
        <div class="aa-ItemPicture aa-ItemPicture--loaded">
          <img
            src="${algoliaShopify.helpers.renderImage(item, 125).src}"
            srcset="${algoliaShopify.helpers.renderImage(item, 125).srcset}"
            sizes="${algoliaShopify.helpers.renderImage(item, 125).sizes}"
            alt="${item.title}"
          />
        </div>
        <div class="aa-ItemContentBody">
          <div class="aa-ItemContentBrand">
            ${
              item.product_type &&
              components.Highlight({ hit: item, attribute: "product_type" })
            }
           removing vendor
          </div>
          <div class="aa-ItemContentTitleWrapper">
            <div class="aa-ItemContentTitle">
              ${components.Highlight({ hit: item, attribute: "title" })}
              <span class="algolia-variant">
                ${algoliaShopify.helpers.variantTitleAddition(item, distinct)}
              </span>
            </div>
          </div>
          <div class="aa-ItemContentPrice">
            <div class="aa-ItemContentPriceCurrent">
              ${algoliaShopify.helpers.displayPrice(item, distinct)}
            </div>
          </div>
        </div>
      </div>
    </a>
  `;
    }
  );
});

beforeAutocompleteArticlesTemplate

Template for rendering each article hit in the autocomplete results. Example:
JavaScript
document.addEventListener("algolia.hooks.initialize", function () {
  algoliaShopify.hooks.registerHook(
    "beforeAutocompleteArticlesTemplate",
    function (_defaultTemplate, templateOptions, itemLink) {
      const { item, html, components } = templateOptions;
      return html`
    <a href="${itemLink}" class="aa-ItemLink">
      <div class="aa-ItemWrapper">
        <div class="aa-ItemContent">
          <div class="aa-ItemIcon aa-ItemIcon--noBorder">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor">
              <path
                stroke-linecap="round"
                stroke-linejoin="round"
                stroke-width="2"
                d="M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-7 7a2 2 0 01-2.828 0l-7-7A1.994 1.994 0 013 12V7a4 4 0 014-4z"
              />
            </svg>
          </div>
          <div class="aa-ItemContentBody">
            <div class="aa-ItemContentTitle">
              ${components.Highlight({ hit: item, attribute: "title" })}
            </div>
          </div>
        </div>
      </div>
    </a>
  `;
    }
  );
});

beforeAutocompleteCollectionsTemplate

Template for rendering each collection hit in the autocomplete results. Example:
JavaScript
document.addEventListener('algolia.hooks.initialize', function() {
  algoliaShopify.hooks.registerHook('beforeAutocompleteCollectionsTemplate', function(_defaultTemplate, templateOptions, itemLink) {
    const { html, item, components } = templateOptions;
    return  html`
      <a href="${itemLink}" class="aa-ItemLink">
        <div class="aa-ItemWrapper">
          <div class="aa-ItemContent">
            <div class="aa-ItemIcon aa-ItemIcon--noBorder">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor">
                <path
                  stroke-linecap="round"
                  stroke-linejoin="round"
                  stroke-width="2"
                  d="M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zM14 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z"
                />
              </svg>
            </div>
            <div class="aa-ItemContentBody">
              <div class="aa-ItemContentTitle">
                ${components.Highlight({ hit: item, attribute: 'title' })}
              </div>
            </div>
          </div>
        </div>
      </a>
    `;
  });
});

beforeAutocompletePagesTemplate

Template for rendering each pages hit in the autocomplete results. Example:
JavaScript
document.addEventListener('algolia.hooks.initialize', function() {
  algoliaShopify.hooks.registerHook('beforeAutocompletePagesTemplate', function(_defaultTemplate, templateOptions, itemLink) {
    const { html, item, components } = templateOptions;
    return html`
      <a href="${itemLink}" class="aa-ItemLink aa-ProductItem">
        <div class="aa-ItemWrapper">
          <div class="aa-ItemContent">
            <div class="aa-ItemIcon aa-ItemIcon--noBorder">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor">
                <path
                  stroke-linecap="round"
                  stroke-linejoin="round"
                  stroke-width="2"
                  d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
                />
              </svg>
            </div>
            <div class="aa-ItemContentBody">
              <div class="aa-ItemContentTitle">
                ${components.Highlight({ hit: item, attribute: 'title' })}
              </div>
            </div>
          </div>
        </div>
      </a>
    `;
  });
});

beforeAutocompleteSuggestionsTemplate

Template for rendering each search suggestion in the autocomplete menu. Example:
JavaScript
document.addEventListener('algolia.hooks.initialize', function() {
  algoliaShopify.hooks.registerHook('beforeAutocompleteSuggestionsTemplate', function(_defaultTemplate, templateOptions) {
    const { html, state } = templateOptions;
    return html`
      <a
        class="aa-ItemLink aa-ItemWrapper"
        href="${window.Shopify.routes.root}search?q=${item.query}"
      >
        <div class="aa-ItemContent">
          <div class="aa-ItemIcon aa-ItemIcon--noBorder">
            <svg viewBox="0 0 24 24" fill="currentColor">
              <path d="M16.041 15.856c-0.034 0.026-0.067 0.055-0.099 0.087s-0.060 0.064-0.087 0.099c-1.258 1.213-2.969 1.958-4.855 1.958-1.933 0-3.682-0.782-4.95-2.050s-2.050-3.017-2.050-4.95 0.782-3.682 2.050-4.95 3.017-2.050 4.95-2.050 3.682 0.782 4.95 2.050 2.050 3.017 2.050 4.95c0 1.886-0.745 3.597-1.959 4.856zM21.707 20.293l-3.675-3.675c1.231-1.54 1.968-3.493 1.968-5.618 0-2.485-1.008-4.736-2.636-6.364s-3.879-2.636-6.364-2.636-4.736 1.008-6.364 2.636-2.636 3.879-2.636 6.364 1.008 4.736 2.636 6.364 3.879 2.636 6.364 2.636c2.125 0 4.078-0.737 5.618-1.968l3.675 3.675c0.391 0.391 1.024 0.391 1.414 0s0.391-1.024 0-1.414z" />
            </svg>
          </div>
          <div class="aa-ItemContentBody">
            <div class="aa-ItemContentTitle">
              ${components.Highlight({ hit: item, attribute: 'query' })}
            </div>
          </div>
        </div>
        <div class="aa-ItemActions">
          <button
            class="aa-ItemActionButton"
            title={"Fill query with ${item.query}"}
          >
            <svg viewBox="0 0 24 24" fill="currentColor">
              <path d="M8 17v-7.586l8.293 8.293c0.391 0.391 1.024 0.391 1.414 0s0.391-1.024 0-1.414l-8.293-8.293h7.586c0.552 0 1-0.448 1-1s-0.448-1-1-1h-10c-0.552 0-1 0.448-1 1v10c0 0.552 0.448 1 1 1s1-0.448 1-1z" />
            </svg>
          </button>
        </div>
      </a>
    `;
  });
});

beforeAutocompleteProductTransformResponseHits

Modifies the hits before rendering them in the autocomplete menu. For more information, see transformresponse. Example:
JavaScript
document.addEventListener('algolia.hooks.initialize', function() {
  algoliaShopify.hooks.registerHook('beforeAutocompleteProductTransformResponseHits', function(hits, results) {
    console.log(hits);
    return hits;
  });
});

afterAutocompleteProductClickAction

Deprecated since March 31, 2025
Use beforeAutocompleteProductTemplate instead. Add click events to the template. Function that should run after a product is clicked. Example:
JavaScript
document.addEventListener('algolia.hooks.initialize', function() {
  algolia.shopify.hooks.registerHook('afterAutocompleteProductClickAction', function(_, line_item) {
    return;
  })
});

InstantSearch hooks

Hooks in this section change the behavior of the search results page.

beforeInstantSearchAsyncFunction

This hook waits for any asynchronous function, such as an external API request, to complete before continuing. It runs before any InstantSearch parameters are set. You can include multiple await statements within this hook to handle several asynchronous operations sequentially. Example:
JavaScript
const sleep = (ms, hookName) => new Promise(resolve => {
  console.log("sleeping for ", ms, hookName);
  setTimeout(resolve, ms);
});

document.addEventListener('algolia.hooks.initialize', function() {
  algoliaShopify.hooks.registerHook('beforeInstantSearchAsyncFunction', async function() {
    console.log("----------- beforeInstantSearchAsyncFunction started ----------------")
    await sleep(1000, 'beforeInstantSearchAsyncFunction');
  });
});

beforeInstantSearchConfigurationOptions

Changes InstantSearch options. Example:
JavaScript
document.addEventListener('algolia.hooks.initialize', function() {
  algoliaShopify.hooks.registerHook('beforeInstantSearchConfigurationOptions', function(options) {
    // Modify default options, then return them
    options.numberLocale: 'fr';
    options.stalledSearchDelay: 500;
    return options;
  });
});

beforeInstantSearchOptions

Changes the following parameters:
  • colors
  • distinct
  • facets
  • hitsPerPage
  • selector
  • sortOrders

beforeInstantSearchAllowParamsArray

Preserves URL parameters when navigating through the search results. Example:
JavaScript
document.addEventListener('algolia.hooks.initialize', function() {
  algoliaShopify.hooks.registerHook('beforeInstantSearchAllowParamsArray', function(allowParamsArray) {
    // Modify default array, then return an array
    allowParamsArray.push('ref');
    return allowParamsArray;
  });
});

beforeInstantSearchFiltersString

Changes the filter parameter of the search results page. Example:
JavaScript
// Modify default `defaultFilter` if it exists
document.addEventListener('algolia.hooks.initialize', function() {
  algoliaShopify.hooks.registerHook('beforeInstantSearchFiltersString', function(defaultFilter) {
    // Modify or replace the default string, then return a string
    if(defaultFilter) {
      return defaultFilter + ' AND price > 5'
    }
    else {
      return 'price > 5'
    }
  });
});

beforeInstantSearchMainTemplate

Template for the main template container. If you’re using the facet display feature, include a div with class="ais-facets-container" to display the facets. For example:
JavaScript
document.addEventListener('algolia.hooks.initialize', function() {
  algoliaShopify.hooks.registerHook('beforeInstantSearchMainTemplate', function(_defaultTemplate, data, html) {
    return html`
      <div class="ais-page">
        <h1 class="ais-h2">${algoliaShopify.translations.searchTitle}</h1>
        <div class="ais-input">
          <div class="ais-search-box-container"></div>
          <div class="ais-input-button">
            <div class="ais-clear-input-icon"></div>
          </div>
        </div>
        <div class="ais-facets-button">
          ${algoliaShopify.translations.showFilters}
        </div>
        <div class="ais-facets">
          <div class="ais-clear-refinements-container"></div>
          <div class="ais-current-refined-values-container"></div>
          ${algoliaShopify.config.app_blocks_dynamic_widgets_beta_enabled
            ? html`
                <div class="ais-dynamic-widgets-container"></div>
              `
            : data.facets.map(
                facet =>
                  html`
                    <div
                      class="ais-facet-dropdown-wrapper ais-facet-${facet.type} ais-facet-${facet.escapedName}"
                    >
                      <label
                        for="${facet.escapedName}"
                        class="ais-range-slider--header ais-facet--header ais-header"
                        >${facet.title}</label
                      >
                      <input
                        class="ais-dropdown-checkbox"
                        type="checkbox"
                        id="${facet.escapedName}"
                        name="dropdown"
                      />
                      <div
                        class="ais-facet-${facet.escapedName}-container ais-facet-dropdown-container"
                      ></div>
                    </div>
                  `
              )}
        </div>
        <div class="ais-block">
          <div class="ais-search-header">
            <div class="ais-stats-container"></div>
            <div class="ais-change-display">
              <span class="ais-change-display-block ais-change-display-selected"
                ><i class="fa fa-th-large"></i
              ></span>
              <span class="ais-change-display-list"
                ><i class="fa fa-th-list"></i
              ></span>
            </div>
            <div class="ais-sort">
              ${data.multipleSortOrders
                ? html`
                    ${algoliaShopify.translations.sortBy}
                    <span class="ais-sort-orders-container"></span>
                  `
                : html`
                    ${algoliaShopify.translations.sortBy}
                    ${algoliaShopify.translations.relevance}
                  `}
            </div>
          </div>
          <div class="ais-hits-container ais-results-as-block"></div>
        </div>
        <div class="ais-pagination-container"></div>
      </div>
    `;
  });
});

beforeInstantSearchProductTemplate

Template for product hits in the search results. If you are using this template, ensure you also call algoliaShopify.hooks.handleItemClick(item) to properly handle events. Example:
JavaScript
document.addEventListener('algolia.hooks.initialize', function() {
  algoliaShopify.hooks.registerHook('beforeInstantSearchProductTemplate', function(_defaultTemplate, hit, html, components) {
    return html`
      <div
        class="ais-hit ais-product"
        data-algolia-index="${hit.index}"
        data-algolia-position="${hit.productPosition}"
        data-algolia-queryid="${hit.queryID}"
        data-algolia-objectid="${hit.objectID}"
        data-handle="${hit.handle}"
        data-variant-id="${hit.objectID}"
        data-distinct="${hit._distinct}"
        data-product-id="${hit.id}"
        onClick="${() => algoliaShopify.helpers.handleItemClick(hit)}"
      >
        <img
          class="ais-hit--picture"
          src="${algoliaShopify.helpers.mediumImage(hit)}"
          alt="${hit.title} - ${hit.variant_title}"
        />

        <div class="ais-hit--details">
          <p class="ais-hit--title">
            <a
              data-algolia-index="${hit.index}"
              data-algolia-position="${hit.productPosition}"
              data-algolia-queryid="${hit.queryID}"
              data-algolia-objectid="${hit.objectID}"
              href="${algoliaShopify.helpers.instantsearchLink(hit)}"
              title="${algoliaShopify.helpers.fullTitle(
                hit.title,
                hit._distinct,
                hit.variant_title
              )}"
            >
              ${components.Highlight({ attribute: 'title', hit })}
              ${algoliaShopify.helpers.variantTitleAddition(hit, hit._distinct)}
            </a>
          </p>
          <p
            class="ais-hit--subtitle"
            title="${hit.product_type}${algoliaShopify.translation_helpers.by(
              hit.vendor
            )}"
          >
            ${components.Highlight({ attribute: 'product_type', hit })}
            ${hit.vendor &&
              html`
                <span> ${algoliaShopify.translations.by} </span>
              `}
            ${hit.vendor && components.Highlight({ attribute: 'vendor', hit })}
          </p>
          <p class="ais-hit--price">
            <b>${algoliaShopify.helpers.displayPrice(hit, hit._distinct)}</b>
            ${!hit._distinct &&
              html`
                <span class="ais-hit--price-striked"
                  ><span
                    >${algoliaShopify.helpers.displayStrikedPrice(
                      hit.price,
                      hit.compare_at_price
                    )}</span
                  ></span
                >
              `}
            ${!hit._distinct &&
              html`
                <span class="ais-hit--price-discount"
                  >${algoliaShopify.helpers.displayDiscount(
                    hit.price,
                    hit.compare_at_price,
                    hit.price_ratio
                  )}</span
                >
              `}
          </p>
          <!-- Extra info examples - Remove the display: none to show them -->
          <p class="ais-hit--info" style="display: none">
            ${hit.sku &&
              html`
                <span class="algolia-sku"
                  >${components.Highlight({ attribute: 'sku', hit })}</span
                >
              `}
            ${hit.barcode &&
              html`
                <span class="algolia-barcode"
                  >${components.Highlight({ attribute: 'barcode', hit })}</span
                >
              `}
            ${hit.weight &&
              html`
                <span class="algolia-weight">${hit.weight}</span>
              `}
            ${!hit.taxable &&
              html`
                <span class="algolia-taxable"
                  >${algoliaShopify.translations.taxFree}</span
                >
              `}
          </p>
          <!-- Tags example - Remove the display: none to show them -->
          <p class="ais-hit--tags" style="display: none">
            ${hit?._highlightResult.tags?.map(
              tag =>
                html`
                  <span class="ais-hit--tag">${tag.value}</span>
                `
            )}
          </p>
          ${!hit._distinct &&
            html`
              <form
                id="algolia-add-to-cart-${hit.objectID}"
                style="display: none;"
                action="/cart/add"
                method="post"
                enctype="multipart/form-data"
              >
                <input type="hidden" name="id" value="${hit.objectID}" />
              </form>
              <p class="ais-hit--cart">
                ${hit.can_order
                  ? html`
                      <button
                        class="ais-hit--cart-button"
                        data-form-id="algolia-add-to-cart-${hit.objectID}"
                      >
                        ${algoliaShopify.translations.addToCart}
                      </button>
                    `
                  : html`
                      <button
                        class="ais-hit--cart-button ais-hit--cart-button__disabled"
                      >
                        ${algoliaShopify.translations.outOfStock}
                      </button>
                    `}
              </p>
            `}
        </div>
      </div>
    `;
  });
});

beforeInstantSearchNoResultTemplate

Template for when there are no results. Example:
JavaScript
document.addEventListener('algolia.hooks.initialize', function() {
  algoliaShopify.hooks.registerHook('beforeInstantSearchNoResultTemplate', function(_defaultTemplate, html) {
    return html`
      <div class="ais-hit-empty">
        <div class="ais-hit-empty--title">
          ${algoliaShopify.translations.noResultFound}
        </div>
        <div class="ais-hit-empty--clears">
          ${algoliaShopify.translations.try} ${' '}
          <a class="ais-hit-empty--clear-filters ais-link">
            ${algoliaShopify.translations.clearFilters} ${' '}
          </a>
          ${algoliaShopify.translations.or} ${' '}
          <a class="ais-hit-empty--clear-input ais-link">
            ${algoliaShopify.translations.changeInput}
          </a>
        </div>
      </div>
    `;
  });
});

beforeInstantSearchFacetItemTemplate

Deprecated since March 31, 2025.
Use beforeInstantSearchFacetParamsOptions instead. The refinementList widget can be added as a parameter within the template object. Template for rendering facet items. Example:
JavaScript
document.addEventListener('algolia.hooks.initialize', function() {
  algoliaShopify.hooks.registerHook('beforeInstantSearchFacetItemTemplate', function(_defaultTemplate, item, html) {
    return html`
      <label class="${item.cssClasses.label}">
        ${item.type === 'disjunctive' &&
          (item.isRefined
            ? html`
                <input
                  type="checkbox"
                  class="${item.cssClasses.checkbox}"
                  checked
                />
              `
            : html`
                <input type="checkbox" class="${item.cssClasses.checkbox}" />
              `)}
        ${item.label}
        <span class="${item.cssClasses.count}">
          ${algoliaShopify.helpers.formatNumber(item.count)}
        </span>
      </label>
    `;
  });
});

beforeInstantSearchShowMoreTemplate

Deprecated since March 31, 2025.
Use beforeInstantSearchFacetParamsOptions instead. The refinementList widget can be added as a parameter within the template object. Template for the showMoreText button Example:
JavaScript
document.addEventListener('algolia.hooks.initialize', function() {
  algoliaShopify.hooks.registerHook('beforeInstantSearchShowMoreTemplate', function(_defaultTemplate, data, html) {
    return html`
      <span
        >${data.isShowingMore
          ? algoliaShopify.translations.showLess
          : algoliaShopify.translations.showMore}</span
      >
    `;
  });
});

beforeInstantSearchStatsTemplate

Template for search stats Example:
JavaScript
document.addEventListener('algolia.hooks.initialize', function() {
  algoliaShopify.hooks.registerHook('beforeInstantSearchStatsTemplate', function(_defaultTemplate, data, html) {
    return html`
      ${data.hasOneResult &&
        html`
          <span class="ais-stats--nb-results">
            1 result found
          </span>
        `}
      ${data.hasManyResults &&
        html`
          ${data.page * data.hitsPerPage + 1} - ${' '}
          ${Math.min((data.page + 1) * data.hitsPerPage, data.nbHits)} ${' '}
          out of
          <span class="ais-stats--nb-results">
            ${' '} ${algoliaShopify.helpers.formatNumber(data.nbHits)} ${' '}
            results found
          </span>
        `}
      ${' '} in ${data.processingTimeMS / 1000}s
    `;
  });
});

beforeISTransformItems

Change items before they’re rendered.
JavaScript
document.addEventListener('algolia.hooks.initialize', function() {
  algoliaShopify.hooks.registerHook('beforeISTransformItems', function(transformedItems, items) {
    return transformedItems;
  });
});

beforeISStartAddWidgetArray

Add InstantSearch widgets to the search results page. You can add the following widgets:
  • rangeSlider
  • menu
  • refinementList
  • searchBox
  • stats
  • sortBy
  • clearRefinements
  • panel
  • hits
  • pagination
  • configure
Example:
JavaScript
document.addEventListener('algolia.hooks.initialize', function() {
  algoliaShopify.hooks.registerHook('beforeISStartAddWidgetArray', function() {
    // Please be aware not all widgets are available
    const { searchBox } = window.algoliaShopify.externals.widgets;

    const searchBoxWidget = searchBox({
      container: '#search-box'
    });

    return [searchBoxWidget];
  });
});

afterISStartRemoveDefaultWidget

Remove default widgets from the search results page. You can remove these widgets (widget.widgetType):
  • ais.sortBy
  • ais.searchBox
  • ais.stats
  • ais.hits
  • ais.pagination
Example:
JavaScript
document.addEventListener('algolia.hooks.initialize', function() {
  algoliaShopify.hooks.registerHook('afterISStartRemoveDefaultWidget', function(defaultWidgets) {
    // Find and return the default pagination widget
    const defaultPaginationWidget = defaultWidgets.find(
      widget => widget.$$widgetType === 'ais.pagination'
    );

    return [defaultPaginationWidget];
  });
});

afterInstantSearchHitClickAction

Deprecated since March 31, 2025.
Use beforeInstantSearchProductTemplate instead. Add click events to the template. Run a function after a search result is clicked. This function must return a function to override the default behavior. Example:
JavaScript
document.addEventListener('algolia.hooks.initialize', function() {
  algoliaShopify.hooks.registerHook('afterInstantSEarchHitClickAction', function(_, hit) {
    return function() {
      // Execute custom code here
      console.log('Product clicked', hit);
    }
  });
});

beforeInstantSearchFacetLimitNumber

Deprecated since March 31, 2025.
Use beforeInstantSearchFacetParamsOptions instead. The refinementList widget can be added as a parameter. Changes the limit (default: 10). Example:
JavaScript
// Modify default `limit`
document.addEventListener('algolia.hooks.initialize', function() {
  algoliaShopify.hooks.registerHook('beforeInstantSearchFacetLimitNumber', function(limit) {
    // Modify default limit, then return a number
    return 12;
  });
});

beforeISFacetSearchablePlaceholderString

Deprecated since March 31, 2025.
Use beforeInstantSearchFacetParamsOptions instead. The searchablePlaceholder option can be added as a parameter within the template object. Changes the searchablePlaceholder.

beforeISFacetSearchableNoResultsString

Deprecated since March 31, 2025.
Use beforeInstantSearchFacetParamsOptions instead. The searchableNoResults option can be added as a parameter within the template object. Changes the searchableNoResults. You can return a template literal or a string.

beforeInstantSearchFacetHeaderString

Deprecated since March 31, 2025
Use beforeInstantSearchFacetPanelOptions instead. The header parameter can be added as a parameter in the template object. To avoid duplicate headers, use the beforeInstantSearchMainTemplate hook and remove the ais-facet-dropdown-wrapper container. Changes the facet header string.

beforeInstantSearchFacetTransformItemsOptions

Deprecated since March 31, 2025
Use beforeInstantSearchFacetParamsOptions instead. Use transformItems as a parameter to transform the data.** Transforms items before they’re rendered.

beforeInstantSearchFacetParamsOptions

Update widget parameters before they’re rendered.
  • params:
    • Parameters depend on the widget type. Use the facet.type helper to determine the widget type.
  • facet (read only):
Example:
JavaScript
document.addEventListener('algolia.hooks.initialize', function() {
  algoliaShopify.hooks.registerHook('beforeInstantSearchFacetParamsOptions', function(params, facet) {
    if (facet.title == "Tags") {
      return {
        ...params,
        limit: 5,
        templates: {
          searchableNoResults(data, { html }) {
            return html`<span>No results</span>`;
          },
        },
      }
    }

    if (facet.title == "Vendor") {
      return {
        ...params,
        transformItems(items) {
          return items.map(item => ({
            ...item,
            label: item.label.toUpperCase(),
          }));
        },
      }
    }

    if (facet.type == "slider") {
      return {
        ...params,
        pips: false,
        tooltips: true,
      }
    }

    return {
      ...params
    }
  });
});

beforeInstantSearchFacetPanelOptions

Update the panel parameters before they’re rendered.
  • params
    • Panel parameters can be found in the panel documentation
  • facet
    • title
    • name
Example:
JavaScript
document.addEventListener('algolia.hooks.initialize', function() {
  algoliaShopify.hooks.registerHook('beforeInstantSearchFacetPanelOptions', function(params, facet) {
    if (facet.name == "tags" || facet.title == "Tags") {
      return {
        ...params,
        templates: {
          // To avoid duplicate headers use the `beforeInstantSearchMainTemplate` hook and remove the  'ais-facet-dropdown-wrapper' container
          header(options, { html }) {
            if (options.results) {
              return html`<span class="ais-facet--header">Tags Header (${options.results.nbHits} results)</span>`;
            }
          },
        }
      }
    }

    if (facet.type == "disjunctive") {
      return {
        ...params,
        templates: {
          footer(options, { html }) {
            if (options.results) {
              return html`<span class="ais-facet--footer">Disjunctive footer (${options.results.nbHits} results)</span>`;
            }
          },
          searchableNoResults(data, { html }) {
            return html`<span>No results</span>`;
          },
        }
      }
    }

    return {
      ...params
    }
  });
});

beforeISearchInitSortOrdersArray

Transform sort order before they’re rendered.

beforeISInitCollectionSortOrdersArray

Transform the sort order for collections.

Recommend hooks

The following hooks can be used to change the behavior of recommendations from Algolia Recommend.

beforeRecommendHitTemplate

Can be used to modify the HTML template that renders the panel with recommendations.
JavaScript
document.addEventListener('algolia.hooks.initialize', function() {
  algoliaShopify.hooks.registerHook('beforeRecommendHitTemplate', function(_defaultTemplate, html, item) {
    return html`
      <div
      id="${item.objectID}"
      class="card-wrapper product-card-wrapper underline-links-hover"
    >
      <div
        class="card card--standard card--media"
        style="--ratio-percent: 100%;"
      >
        <div
          id="Card--${item.objectID}"
          class="card__inner gradient ratio"
          style="--ratio-percent: 100%"
        >
          <div class="card__content">
            <div class="card__information">
              <h3 class="card__heading">
                <a
                  id="StandardCardNoMediaLink--${item.objectID}"
                  class="full-unstyled-link"
                  aria-labelledby="StandardCardNoMediaLink--${item.objectID} NoMediaStandardBadge--${item.objectID}"
                >
                  ${item.title}
                </a>
              </h3>
            </div>
            <div class="card__badge bottom left"></div>
          </div>
        </div>
      </div>
    `;
  })
})

Insights hooks

The following hooks change aspects of Insights integration for sending click and conversion events.

beforeAlgoliaAnalyticsOptions

Changes parameters of the Insights library. Example:
JavaScript
document.addEventListener('algolia.hooks.initialize', function() {
  algoliaShopify.hooks.registerHook('beforeAlgoliaAnalyticsOptions', function(options) {
    return {
      ...options
      userHasOptedOut: true
    };
  });
});

beforeAddToCartSelectorString

Changes the CSS selector for the add-to-cart button. Example:
JavaScript
// Modify default `options`
document.addEventListener('algolia.hooks.initialize', function() {
  algoliaShopify.hooks.registerHook('beforeAddToCartSelectorString', function(_selector) {
    // The default selector is '[name="add"]'
    // Return a CSS selector
    return '#add-to-cart';
  });
});
I