UI Libraries / Autocomplete / autocomplete

The autocomplete function creates an autocomplete experience and attaches it to an element of the DOM. By default, it uses Preact 10 to render templates.

Installation

First, you need to install the package.

1
2
3
yarn add @algolia/autocomplete-js
# or
npm install @algolia/autocomplete-js

Then import it in your project:

1
import { autocomplete } from '@algolia/autocomplete-js';

If you don’t use a package manager, you can use the HTML script element:

1
2
3
4
<script src="https://cdn.jsdelivr.net/npm/@algolia/autocomplete-js"></script>
<script>
  const { autocomplete } = window['@algolia/autocomplete-js'];
</script>

Example

Make sure to define an empty container in your HTML where to inject your autocomplete.

1
<div id="autocomplete"></div>

This example uses Autocomplete with an Algolia index, along with the algoliasearch API client. All Algolia utility functions to retrieve hits and parse results are available directly in the package.

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
import algoliasearch from 'algoliasearch/lite';
import { autocomplete, getAlgoliaResults } from '@algolia/autocomplete-js';

const searchClient = algoliasearch(
  'latency',
  '6be0576ff61c053d5f9a3225e2a90f76'
);

const autocompleteSearch = autocomplete({
  container: '#autocomplete',
  getSources() {
    return [
      {
        sourceId: 'querySuggestions',
        getItemInputValue: ({ item }) => item.query,
        getItems({ query }) {
          return getAlgoliaResults({
            searchClient,
            queries: [
              {
                indexName: 'instant_search_demo_query_suggestions',
                query,
                params: {
                  hitsPerPage: 4,
                },
              },
            ],
          });
        },
        templates: {
          item({ item, components }) {
            return <components.ReverseHighlight hit={item} attribute="query" />;
          },
        },
      },
    ];
  },
});

Parameters

container
type: string | HTMLElement
Required

The container for the Autocomplete search box. You can either pass a CSS selector or an Element. If there are several containers matching the selector, Autocomplete picks up the first one.

panelContainer
type: string | HTMLElement

The container for the Autocomplete panel. You can either pass a CSS selector or an Element. If there are several containers matching the selector, Autocomplete picks up the first one.

panelPlacement
type: "start" | "end" | "full-width" | "input-wrapper-width"` | defaults to `"input-wrapper-width"

The panel’s horizontal position.

translations
type: Translations

A dictionary of translations to support internationalization.

1
2
3
4
5
type Translations = Partial<{
  clearButtonTitle: string; // defaults to 'Clear'
  detachedCancelButtonText: string; // defaults to 'Cancel'
  submitButtonTitle: string; // defaults to 'Submit'
}>
classNames
type: ClassNames

Class names to inject for each created DOM element. This is useful to style your autocomplete with external CSS frameworks.

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
type ClassNames = Partial<{
  detachedCancelButton: string;
  detachedFormContainer: string;
  detachedContainer: string;
  detachedOverlay: string;
  detachedSearchButton: string;
  detachedSearchButtonIcon: string;
  detachedSearchButtonPlaceholder: string;
  form: string;
  input: string;
  inputWrapper: string;
  inputWrapperPrefix: string;
  inputWrapperSuffix: string;
  item: string;
  label: string;
  list: string;
  loadingIndicator: string;
  panel: string;
  panelLayout: string;
  clearButton: string;
  root: string;
  source: string;
  sourceFooter: string;
  sourceHeader: string;
  submitButton: string;
}>;
components

Components to register in the Autocomplete rendering lifecycles. Registered components become available in templates, render, and in renderNoResults.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import { render } from 'preact';
import { MyComponent } from './my-components';

autocomplete({
  // ...
  components: {
    MyComponent,
  },
  render({ sections, components }, root) {
    render(
      <Fragment>
        <div className="aa-PanelLayout aa-Panel--scollable">{sections}</div>
        <components.MyComponent />
      </Fragment>,
      root
    );
  },
});

Four components are registered by default:

  • Highlight to highlight matches in Algolia results
  • Snippet to snippet matches in Algolia results
  • ReverseHighlight to reverse highlight matches in Algolia results
  • ReverseSnippet to reverse highlight and snippet matches in Algolia results
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
autocomplete({
  // ...
  getSources({ query }) {
    return [
      {
        getItems() {
          return [
            /* ... */
          ];
        },
        templates: {
          item({ item, components }) {
            return <components.Highlight hit={item} attribute="name" />;
          },
        },
      },
    ];
  },
});
render
type: (params: { children: VNode, elements: Elements, sections: VNode[], state: AutocompleteState<TItem>, createElement: Pragma, Fragment: PragmaFrag }) => void

The function that renders the autocomplete panel. This is useful to customize the rendering, for example, using multi-row or multi-column layouts.

This is the default implementation:

1
2
3
4
5
6
7
8
import { render } from 'preact';

autocomplete({
  // ...
  render({ children }, root) {
    render(children, root);
  },
});

You can use sections, which holds the components tree of your autocomplete, to customize the wrapping layout.

1
2
3
4
5
6
7
8
9
10
11
import { render } from 'preact';

autocomplete({
  // ...
  render({ sections }, root) {
    render(
      <div className="aa-PanelLayout aa-Panel--scrollable">{sections}</div>,
      root
    );
  },
});

If you need to split the content across a more complex layout, you can use elements instead to pick which source to display based on its sourceId.

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
import { createQuerySuggestionsPlugin } from '@algolia/autocomplete-plugin-query-suggestions';
import { createLocalStorageRecentSearchesPlugin } from '@algolia/autocomplete-plugin-recent-searches';
import algoliasearch from 'algoliasearch';
import { render } from 'preact';

const searchClient = algoliasearch(
  'latency',
  '6be0576ff61c053d5f9a3225e2a90f76'
);
const recentSearchesPlugin = createLocalStorageRecentSearchesPlugin({
  key: 'search',
});
const querySuggestionsPlugin = createQuerySuggestionsPlugin({
  searchClient,
  indexName: 'instant_search_demo_query_suggestions',
});

autocomplete({
  // ...
  plugins: [recentSearchesPlugin, querySuggestionsPlugin],
  getSources({ query }) {
    return [
      {
        sourceId: 'products',
        // ...
      },
    ];
  },
  render({ elements }, root) {
    const { recentSearchesPlugin, querySuggestionsPlugin, products } = elements;

    render(
      <div className="aa-PanelLayout aa-Panel--scrollable">
        <div>
          {recentSearchesPlugin}
          {querySuggestionsPlugin}
        </div>
        <div>{products}</div>
      </div>,
      root
    );
  },
});
renderNoResults
type: (params: { children: VNode, state: AutocompleteState<TItem>, sections: VNode[], createElement: Pragma, Fragment: PragmaFrag }) => void

The function that renders a no results section when there are no hits. This is useful to let the user know that the query returned no results.

There’s no default implementation. By default, Autocomplete closes the panel when there’s no results. Here’s how you can customize this behavior:

1
2
3
4
5
6
7
8
import { render } from 'preact';

autocomplete({
  // ...
  renderNoResults({ state }, root) {
    render(`No results for "${state.query}".`, root);
  },
});
renderer

The virtual DOM implementation to plug to Autocomplete. It defaults to Preact.

See renderer.

detachedMediaQuery
type: string
default: "(max-width: 680px)"

The detached mode turns the dropdown display into a full screen, modal experience.

See Detached mode for more information.

renderer ➔ renderer

createElement
type: (type: any, props: Record<string, any> | null, ...children: ComponentChildren[]) => VNode` | defaults to `preact.createElement

The function that create virtual nodes.

It uses Preact 10’s createElement by default, but you can provide your own implementation.

Fragment
default: preact.Fragment

The component to use to create fragments.

It uses Preact 10’s Fragment by default, but you can provide your own implementation.

The autocomplete function also accepts all the props that createAutocomplete supports.

getSources

The sources to get the collections from.

reshape
type: Reshape

The function called to reshape the sources after they’re resolved.

This is useful to transform sources before rendering them. You can group sources by attribute, remove duplicates, create shared limits between sources, etc.

See Reshaping sources for more information.

1
2
3
4
5
type Reshape = (params: {
  sources: AutocompleteReshapeSource[];
  sourcesBySourceId: Record<string, AutocompleteReshapeSource>;
  state: AutocompleteState;
}) => AutocompleteReshapeSource[];
id
type: string
default: "autocomplete-0" (incremented for each instance)

An ID for the autocomplete to create accessible attributes.

onStateChange
type: (params: { state: AutocompleteState<TItem> }) => void

The function called when the internal state changes.

placeholder
type: string

The placeholder text to show in the search input when there’s no query.

autoFocus
type: boolean
default: false

Whether to focus the search input or not when the page is loaded.

defaultActiveItemId
type: number | null
default: null

The default item index to pre-select.

You should use 0 when the autocomplete is used to open links, instead of triggering a search in an application.

openOnFocus
type: boolean
default: false

Whether to open the panel on focus when there’s no query.

stallThreshold
type: number
default: 300

How many milliseconds must elapse before considering the autocomplete experience stalled.

initialState
type: Partial<AutocompleteState>

The initial state to apply when autocomplete is created.

environment
type: typeof window
default: window

The environment in which your application is running.

This is useful if you’re using autocomplete in a different context than window.

navigator
type: Navigator

An implementation of Autocomplete’s Navigator API to redirect the user when opening a link.

Learn more on the Navigator API documentation.

shouldPanelOpen
type: (params: { state: AutocompleteState }) => boolean

The function called to determine whether the panel should open or not.

By default, the panel opens when there are items in the state.

onSubmit
type: (params: { state: AutocompleteState, event: Event, ...setters }) => void

The function called when submitting the Autocomplete form.

onReset
type: (params: { state: AutocompleteState, event: Event, ...setters }) => void

The function called when resetting the Autocomplete form.

debug
type: boolean
default: false

A flag to activate the debug mode.

This is useful while developing because it keeps the panel open even when the blur event occurs. Make sure to turn it off in production.

See Debugging for more information.

plugins

The plugins that encapsulate and distribute custom Autocomplete behaviors.

See Plugins for more information.

Returns

The autocomplete function returns state setters and a refresh method that updates the UI state.

These setters are useful to control the autocomplete experience from external events.

1
2
3
4
5
6
7
8
9
10
11
const {
  setActiveItemId,
  setQuery,
  setCollections,
  setIsOpen,
  setStatus,
  setContext,
  refresh,
  update,
  destroy,
} = autocomplete(options);

The autocomplete function returns state setters and additional helpers:

refresh
type: () => Promise<void>

Updates the UI state. You must call this function whenever you mutate the state with setters and want to reflect the changes in the UI.

update
type: (updatedOptions: Partial<AutocompleteOptions>) => void

Updates the Autocomplete instance with new options.

destroy
type: () => void

Destroys the Autocomplete instance, cleans up the DOM mutations and event listeners.

Did you find this page helpful?