Plugins
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.
Using an Autocomplete plugin
When using an Autocomplete plugin, all you need to do is provide it via the plugins
option.
For example, when using the Insights plugin, you can instantiate the plugin, then pass it down to your Autocomplete instance.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import 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 execute sequentially, in the order you define them.
Building 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.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
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.';
},
},
},
];
});
},
};
}
1
2
3
4
5
6
7
8
9
10
11
import { autocomplete } from '@algolia/autocomplete-js';
import { createGitHubReposPlugin } from './createGitHubReposPlugin';
const gitHubReposPlugin = createGitHubReposPlugin({
per_page: 5,
});
autocomplete({
container: '#autocomplete',
plugins: [gitHubReposPlugin],
});
You can see this demo live on CodeSandbox.
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.
Subscribing 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 the user navigates results. You can use subscribe
to hook into onSelect
and onActive
events and use the Google Analytics API there.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
function createGoogleAnalyticsPlugin({ trackingId, options }) {
return {
subscribe({ onSelect, onActive }) {
ga('create', trackingId, ...options);
const event = {
hitType: 'event',
eventCategory: 'Autocomplete',
eventLabel: item.name,
};
onSelect(({ item }) => {
ga('send', {
...event,
eventAction: 'select',
});
});
onActive(({ item }) => {
ga('send', {
...event,
eventAction: 'active',
});
});
},
};
}
Official plugins
There are a few useful official plugins you can already use with Autocomplete.
autocomplete-plugin-recent-searches
displays a list of the latest searches the user made. It comes with a pre-implemented version that connects with the user’s local storage.autocomplete-plugin-query-suggestions
plugs Algolia Query Suggestions to your autocomplete.autocomplete-plugin-algolia-insights
automatically sends click and conversion events to the Algolia Insights API whenever a user interacts with the autocomplete.autocomplete-plugin-tags
lets you manage and display tags in the autocomplete. You can use tags for a wide variety of use cases: filtering, displaying refinements, representing navigation steps, and more.
Reference
name
|
type: string | undefined
A name to identify the plugin. |
subscribe
|
type: (params: { onSelect: (fn: params: TParams) => void, onActive: (fn: params: TParams) => void, ...setters: AutocompleteSetters }) => void
The function called when Autocomplete starts. |
onStateChange
|
type: (params: { state: AutocompleteState<TItem> }) => void
The function called when the internal state changes. |
onSubmit
|
type: (params: { state: AutocompleteState, event: Event, ...setters: AutocompleteSetters }) => void
The function called when submitting the Autocomplete form. |
onReset
|
type: (params: { state: AutocompleteState, event: Event, ...setters: AutocompleteSetters }) => void
The function called when resetting the Autocomplete form. |
getSources
|
type: (params: { query: string, state: AutocompleteState, ...setters: AutocompleteSetters }) => Array<AutocompleteSource> | Promise<Array<AutocompleteSource>>
The sources to get the suggestions from. When defined, they’re merged with the sources of your Autocomplete instance. |
data
|
type: unknown
An extra plugin object to expose properties and functions as APIs. |