Populating autocomplete with Sources
The most important aspect of an autocomplete experience is the items you display. Most of the time they’re search results to a query, but you could imagine many different usages.
Autocomplete gives you total freedom to return rich suggestions via the Sources API.
Using static sources
The most straightforward way to provide items is to return static sources. Each source returns a collection of items.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
autocomplete({
// ...
getSources() {
return [
{
sourceId: 'links',
getItems() {
return [
{ label: 'Twitter', url: 'https://twitter.com' },
{ label: 'GitHub', url: 'https://github.com' },
];
},
getItemUrl({ item }) {
return item.url;
},
// ...
},
];
},
});
Here, whatever the autocomplete state is, it always returns these two items.
Searching in static sources
You can access the autocomplete state in your sources, meaning you can search within static sources to update them as the user types.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
autocomplete({
// ...
getSources() {
return [
{
sourceId: 'links',
getItems({ query }) {
return [
{ label: 'Twitter', url: 'https://twitter.com' },
{ label: 'GitHub', url: 'https://github.com' },
].filter(({ label }) =>
label.toLowerCase().includes(query.toLowerCase())
);
},
getItemUrl({ item }) {
return item.url;
},
// ...
},
];
},
});
Before moving on to more complex sources, here’s a closer look at the code.
Notice that the getSources
function returns an array of sources. Each source implements a getItems
function to return the items to display. These items can be a simple static array, but you can also use a function to refine items based on the query. The getItems
function is called whenever the input changes.
By default, autocomplete items are meant to be hyperlinks. To determine what URL to navigate to, you can implement a getItemURL
function. It enables the keyboard accessibility feature, allowing users to open items in the current tab, a new tab, or a new window from their keyboard.
Customizing items with templates
In addition to defining data sources for items, a source also lets you customize how to display items using templates
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
autocomplete({
// ...
getSources({ query }) {
return [
{
// ...
templates: {
item({ item }) {
return `Result: ${item.name}`;
},
},
},
];
},
});
You can also display header and footer elements around the list of items.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
autocomplete({
// ...
getSources({ query }) {
return [
{
// ...
templates: {
header() {
return 'Suggestions';
},
item({ item }) {
return `Result: ${item.name}`;
},
footer() {
return 'Footer';
},
},
},
];
},
});
Templates aren’t limited to strings. You can provide anything as long as they’re a valid virtual DOM element (see more in Templates).
Using dynamic sources
Static sources can be useful, especially when the user hasn’t typed anything yet. However, you might want more robust search capabilities beyond exact matches in strings.
In this case, you could search into one or more Algolia indices using the built-in getAlgoliaResults
function.
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
import algoliasearch from 'algoliasearch/lite';
import { autocomplete, getAlgoliaResults } from '@algolia/autocomplete-js';
const searchClient = algoliasearch(
'latency',
'6be0576ff61c053d5f9a3225e2a90f76'
);
autocomplete({
// ...
getSources() {
return [
{
sourceId: 'products',
getItems({ query }) {
return getAlgoliaResults({
searchClient,
queries: [
{
indexName: 'instant_search',
query,
},
],
});
},
getItemUrl({ item }) {
return item.url;
},
// ...
},
];
},
});
Using asynchronous sources
The getSources
function supports promises so that you can fetch sources from any asynchronous API. It can be Algolia or any third-party API you can query with an HTTP request.
For example, you could use the Query Autocomplete service of the Google Places API to search for places and retrieve popular queries that map to actual points of interest.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
autocomplete({
// ...
getSources({ query }) {
return fetch(
`https://maps.googleapis.com/maps/api/place/queryautocomplete/json?input=${query}&key=YOUR_GOOGLE_PLACES_API_KEY`
)
.then((response) => response.json())
.then(({ predictions }) => {
return [
{
sourceId: 'predictions',
getItems() {
return predictions;
},
getItemInputValue({ item }) {
return item.description;
},
// ...
},
];
});
},
});
Note the usage of the getItemInputValue
function to return the value of the item. It lets you fill the search box with a new value whenever the user selects an item, allowing them to refine their query and retrieve more relevant results.
Using multiple sources
An autocomplete experience doesn’t have to return only a single set of results. Autocomplete lets you fetch from different sources and display different types of results that serve different purposes.
For example, you may want to display Algolia search results and Query Suggestions based on the current query to let users refine it and yield better results.
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
import algoliasearch from 'algoliasearch/lite';
import { autocomplete, getAlgoliaResults } from '@algolia/autocomplete-js';
const searchClient = algoliasearch(
'latency',
'6be0576ff61c053d5f9a3225e2a90f76'
);
autocomplete({
// ...
getSources({ query }) {
return [
{
sourceId: 'querySuggestions',
getItems() {
return getAlgoliaResults({
searchClient,
queries: [
{
indexName: 'instant_search_demo_query_suggestions',
query,
},
],
});
},
getItemInputValue() {
return item.query;
},
// ...
},
{
sourceId: 'products',
getItems() {
return getAlgoliaResults({
searchClient,
queries: [
{
indexName: 'instant_search',
query,
},
],
});
},
getItemUrl({ item }) {
return item.url;
},
// ...
},
];
},
});
You can use the official autocomplete-plugin-query-suggestions
plugin to retrieve Query Suggestions from Algolia.
For more information, check out the guide on adding multiple sources to one autocomplete.
Reference
getSources
|
type: (params: { query: string, state: AutocompleteState, ...setters: Autocomplete Setters }) => Array<AutocompleteSource> | Promise<Array<AutocompleteSource>>
The function to fetch sources and their behaviors. See source for what to return. |
source ➔ source
sourceId
|
type: string
Unique identifier for the source. It’s used as value for the |
||
getItems
|
type: (params: { query: string, state: AutocompleteState, ...setters }) => Item[] | Promise<Item[]>
Required
The function called when the input changes. You can use this function to filter the items based on the query. |
||
Copy
|
|||
getItemInputValue
|
type: (params: { item, state: AutocompleteState }) => string` | defaults to `({ state }) => state.query
The function called to get the value of an item. The value is used to fill the search box. |
||
Copy
|
|||
getItemUrl
|
type: (params: { item: Item, state: AutocompleteState }) => string | undefined
The function called to get the URL of the item. The value is used to add keyboard accessibility features to let users open items in the current tab, a new tab, or a new window. |
||
Copy
|
|||
onSelect
|
type: (params: { state: AutocompleteState, ...setters, event: Event, item: TItem, itemInputValue: string, itemUrl: string, source: AutocompleteSource }) => void` | defaults to `({ setIsOpen }) => setIsOpen(false)
The function called whenever an item is selected. |
||
onActive
|
type: (params: { state: AutocompleteState, ...setters, event: Event, item: TItem, itemInputValue: string, itemUrl: string, source: AutocompleteSource }) => void
The function called whenever an item is active. You can trigger different behaviors if the item is active depending on the triggering event using the |
||
templates
|
type: AutocompleteTemplates
A set of templates to customize how sections and their items are displayed. See Displaying items with Templates for more information. |