Skip to main content
An autocomplete can be much more than a functional combo box. Autocomplete lets you extend and encapsulate custom behavior with its Plugin API. For example, the official Algolia Insights plugin automatically sends click and conversion events to the Algolia Insights API whenever a user interacts with the autocomplete. You can use one of the existing official plugins or build your own. See demo

Use Autocomplete plugins

When using an Autocomplete plugin, all you need to do is provide it with the plugins option. For example, when using the Insights plugin, you can instantiate the plugin, then pass it down to your Autocomplete instance.
JavaScript
import { liteClient as algoliasearch } from "algoliasearch/lite";
import { autocomplete } from "@algolia/autocomplete-js";
import { createAlgoliaInsightsPlugin } from "@algolia/autocomplete-plugin-algolia-insights";
import insightsClient from "search-insights";

const appId = "latency";
const apiKey = "6be0576ff61c053d5f9a3225e2a90f76";
const searchClient = algoliasearch(appId, apiKey);

insightsClient("init", { appId, apiKey });

const algoliaInsightsPlugin = createAlgoliaInsightsPlugin({ insightsClient });

autocomplete({
  // ...
  plugins: [algoliaInsightsPlugin],
});
Plugins run sequentially, in the order you define them.

Build your own plugin

An Autocomplete plugin is an object that implements the AutocompletePlugin interface. It can provide sources, react to state changes, and hook into various autocomplete lifecycle steps. It has access to setters, including the Context API, allowing it to store and retrieve arbitrary data at any time. The following example creates a plugin that searches into a static list of GitHub repositories.
JavaScript
const gitHubReposPlugin = {
  getSources() {
    return [
      {
        sourceId: "githubPlugin",
        getItems({ query }) {
          return [
            { name: "algolia/autocomplete", stars: 1237 },
            { name: "algolia/algoliasearch-client-javascript", stars: 884 },
            { name: "algolia/algoliasearch-client-php", stars: 554 },
          ].filter(({ name }) =>
            name.toLowerCase().includes(query.toLowerCase()),
          );
        },
        getItemUrl({ item }) {
          return `https://github.com/${item.name}`;
        },
        templates: {
          item({ item }) {
            const stars = new Intl.NumberFormat("en-US").format(item.stars);

            return `${item.name} (${stars} stars)`;
          },
          noResults() {
            return "No results.";
          },
        },
      },
    ];
  },
};

autocomplete({
  // ...
  plugins: [gitHubReposPlugin],
});
If you want to package and distribute your plugin for other people to use, you might want to expose a function instead. For example, you can use the GitHub API to search into all repositories, and let people pass API parameters as plugin options.
JavaScript
import qs from "qs";

function debouncePromise(fn, time) {
  let timerId = undefined;

  return function (...args) {
    if (timerId) {
      clearTimeout(timerId);
    }

    return new Promise((resolve) => {
      timerId = setTimeout(() => resolve(fn(...args)), time);
    });
  };
}

const debouncedFetch = debouncePromise(fetch, 300);

const baseUrl = `https://api.github.com/search/repositories`;

export function createGitHubReposPlugin(options) {
  return {
    getSources({ query }) {
      const queryParameters = qs.stringify({ ...options, q: query });
      const endpoint = [baseUrl, queryParameters].join("?");

      return debouncedFetch(endpoint)
        .then((response) => response.json())
        .then((repositories) => {
          return [
            {
              sourceId: "githubPlugin",
              getItems() {
                return repositories.items;
              },
              getItemUrl({ item }) {
                return item.html_url;
              },
              templates: {
                item({ item }) {
                  const stars = new Intl.NumberFormat("en-US").format(
                    item.stargazers_count,
                  );

                  return `${item.full_name} (${stars} stars)`;
                },
                noResults() {
                  return "No results.";
                },
              },
            },
          ];
        });
    },
  };
}
JavaScript
import { autocomplete } from "@algolia/autocomplete-js";
import { createGitHubReposPlugin } from "./createGitHubReposPlugin";

const gitHubReposPlugin = createGitHubReposPlugin({
  per_page: 5,
});

autocomplete({
  container: "#autocomplete",
  plugins: [gitHubReposPlugin],
});
The GitHub Search API is rate limited, which means you need to debounce calls to avoid 403 errors. For instant search results with no rate limiting, highlighted results, flexible custom ranking, and more, you can index repositories into Algolia instead.

Subscribe to source lifecycle hooks

When building, you also get access to the subscribe method. It runs once when the autocomplete instance starts and lets you subscribe to lifecycle hooks and interact with the instance’s state and context. For example, imagine you want to build a plugin that sends events to Google Analytics when users navigate results. You can use subscribe to hook into onSelect and onActive events and use the Google Analytics API there.
JavaScript
function createGoogleAnalyticsPlugin({ trackingId, options }) {
  return {
    subscribe({ onSelect, onActive }) {
      gtag("config", "<YOUR_GOOGLE_TAG_ID>", ...options);

      onSelect(({ item }) => {
        gtag("event", "select_item", {
          item_list_name: "Autocomplete",
          items: [
            {
              item_id: item.__autocomplete_id,
              item_name: item.name,
            },
          ],
        });
      });

      onActive(({ item }) => {
        gtag("event", "active_item", {
          item_list_name: "Autocomplete",
          items: [
            {
              item_id: item.__autocomplete_id,
              item_name: item.name,
            },
          ],
        });
      });
    },
  };
}

Official plugins

Reference

name
string | undefined
A name to identify the plugin.
subscribe
function
Type definition
(params: {
  onSelect: (fn: params: TParams) => void, 
  onActive: (fn: params: TParams) => void,
  ...setters: AutocompleteSetters 
}) => void
The function called when Autocomplete starts.
onStateChange
function
Type definition
(params: { state: AutocompleteState<TItem> }) => void
The function called when the internal state changes.
onSubmit
function
Type definition
(params: { state: AutocompleteState, event: Event, ...setters: AutocompleteSetters }) => void
The function called when submitting the Autocomplete form.
onReset
function
Type definition
(params: { state: AutocompleteState, event: Event, ...setters: AutocompleteSetters }) => void
The function called when resetting the Autocomplete form.
getSources
function
Type definition
(params: { 
  query: string,
  state: AutocompleteState,
  ...setters: AutocompleteSetters 
}) => Array<AutocompleteSource> | Promise<Array<AutocompleteSource>>
The sources to get the suggestions from.
data
An extra plugin object to expose properties and functions as APIs.
I