UI Libraries / Autocomplete / Upgrading

Autocomplete v1 offers many new features that are explained in Core concepts. Please read this documentation to understand the new capabilities.

Import

1
2
3
4
5
// Before
import autocomplete from 'autocomplete.js';

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

Container

Autocomplete now takes a container (for example, a <div>), not an <input>. Autocomplete generates a fully accessible search box for you.

1
2
3
4
5
<!-- Autocomplete v0.x -->
<input id="autocomplete" />

<!-- Autocomplete v1.x -->
<div id="autocomplete"></div>

Read more about installation options in the Getting Started guide.

Parameters

These parameters and how you use them have changed from Autocomplete v0:

v0 v1
autocomplete('#autocomplete', /* ... */) autocomplete({ container: '#autocomplete', /* ... */ })
autoselect: true defaultActiveItemId: 0
autoselectOnBlur: true No longer needed; this is the default behavior
tabAutocomplete: true No longer supported; v1 implements the ARIA 1.1 form of the combobox design pattern
hint No longer supported
clearOnSelected This is now local to the source: getItemInputValue: () => ''
dropdownMenuContainer panelContainer
templates (top-level) templates (see also render and renderNoResults)
cssClasses classNames where properties have changed
keyboardShortcuts No longer supported as an option; check out the keyboard navigation docs
minLength: 0 openOnFocus: true

Datasets

Datasets are replaced by the getSources function. Learn more about Sources concept.

Sources

Sources are replaced by getItems.

Templates

Autocomplete v1.x renamed some templates, and uses an agnostic virtual DOM implementation to render them.

Returning HTML

Unlike in v0.x, you can no longer return plain HTML strings to inject into the DOM. Yet, you can still return HTML strings using the provided html tagged function.

The html function is only available starting from v1.6.0.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
autocomplete(
  // ...
  [
    {
      // ...
      templates: {
        header: '<div class="header">Products</div>',
        suggestion: function (item) {
          const name = item._highlightResult.name.value;

          return `<div>
            <img class="thumbnail" src="${item.image}" />
            <a href="${item.url}">${autocomplete.escapeHighlightedString(
              name,
              '<em>',
              '</em>'
            )}</a>
          </div>`;
        },
      },
    },
  ]
);

Please refer to the Returning HTML section of the Templates guide for a full overview and to learn how to support Internet Explorer 11.

If you’re already using a virtual DOM in your application, you can provide it to Autocomplete and directly return JSX from templates.

Renamed templates

Some templates from v0.x were renamed in v1.x.

  • The suggestion template is now item.
  • The empty template is now noResults.

New renderer.render option

Starting from v1.6.0, Autocomplete introduces a new render property in the renderer option to pass a custom render function when using Autocomplete with a custom virtual DOM implementation (React, Vue).

If you were using the render option to specify a custom render function, you can now remove it and pass the function to renderer instead.

1
2
3
4
5
6
7
8
9
10
import { createElement, Fragment } from 'react';
import { render } from 'react-dom';

autocomplete({
  // ...
  renderer: { createElement, Fragment },
  render({ children }, root) {
    render(children, root);
  },
});

If you were using the render option to customize the layout, you can also leverage the new renderer.render option and access your custom render function in the provided render parameters.

1
2
3
4
5
6
7
8
9
10
import { createElement, Fragment } from 'react';
import { render } from 'react-dom';

autocomplete({
  // ...
  renderer: { createElement, Fragment },
  render({ children }, root) {
    render(`<div>${children}</div>`, root);
  },
});

Top-level API

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Before
const search = autocomplete(/* ... */);
search.autocomplete.open();
search.autocomplete.close();
search.autocomplete.getVal();
search.autocomplete.setVal('Query');
search.autocomplete.destroy();

// After
const search = autocomplete(/* ... */);
search.setIsOpen(true);
search.setIsOpen(false);
search.setQuery('Query');
search.destroy();

Full example

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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// Autocomplete v0.x
import autocomplete from 'autocomplete.js';

autocomplete(
  '#autocomplete',
  {
    cssClasses: {
      dropdownMenu: 'search-suggestion-wrapper',
    },
  },
  [
    {
      source: autocomplete.sources.hits(searchClient.initIndex('products'), {
        hitsPerPage: 3,
        distinct: true,
      }),
      templates: {
        header: '<div class="header">Products</div>',
        suggestion: function (item) {
          const name = item._highlightResult.name.value;

          return `<div>
            <img class="thumbnail" src="${item.image}" />
            <a href="${item.url}">${autocomplete.escapeHighlightedString(
            name,
            '<em>',
            '</em>'
          )}</a>
          </div>`;
        },
      },
    },
  ]
);

// Autocomplete v1.x
import { autocomplete, getAlgoliaResults } from '@algolia/autocomplete-js';

autocomplete({
  container: '#autocomplete',
  classNames: {
    panel: 'search-suggestion-wrapper',
  },
  getSources({ query }) {
    return [
      {
        sourceId: 'products',
        getItems({ query }) {
          return getAlgoliaResults({
            searchClient,
            queries: [
              {
                indexName: 'products',
                query,
                params: {
                  hitsPerPage: 3,
                  distinct: true,
                },
              },
            ],
          });
        },
        templates: {
          header({ createElement }) {
            return createElement('div', { class: 'header' }, 'Products');
          },
          item({ item, createElement, components }) {
            return createElement(
              'div',
              null,
              createElement(
                'img',
                { class: 'thumbnail', src: item.image },
                createElement(
                  'a',
                  { href: item.url },
                  components.Highlight({
                    hit: item,
                    attribute: 'name',
                    tagName: 'em',
                  })
                )
              )
            );
          },
        },
      },
    ];
  },
});
Did you find this page helpful?