UI Libraries / Autocomplete / Getting Started

Get started with Autocomplete by building an Algolia search experience.

This documentation offers a few ways to learn about the Autocomplete library:

  • Read the Core Concepts to learn more about underlying principles, like Sources and State.
  • Follow the Guides to understand how to build common UX patterns.
  • Refer to API reference for a comprehensive list of parameters and options.
  • Try out the Playground where you can fork a basic implementation and play around.

Keep reading to see how to install Autocomplete and build a basic implementation with Algolia.

Installation

The recommended way to get started is with the autocomplete-js package. It includes everything you need to render a JavaScript autocomplete experience.

Otherwise, you can install the autocomplete-core package if you want to build a renderer from scratch.

All Autocomplete packages are available on the npm registry.

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

If you don’t want to use a package manager, you can use a standalone endpoint:

1
<script src="https://cdn.jsdelivr.net/npm/@algolia/autocomplete-js"></script>

Algolia recommends using jsDelivr but autocomplete-js is also available through unpkg.

Install the Autocomplete Classic Theme

The Autocomplete library provides the autocomplete-theme-classic package so that you can have sleek styling out of the box.

If you want a custom theme, you can use this classic theme and customize it with CSS variables. You can also create a new theme entirely using the classic theme as a starting point.

This example uses the out of the box classic theme. You can import it like any other Autocomplete package.

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

Then import it in your project:

1
import '@algolia/autocomplete-theme-classic';

If you don’t use a package manager, you can link the style sheet in your HTML:

1
2
3
4
<link
  rel="stylesheet"
  href="https://cdn.jsdelivr.net/npm/@algolia/autocomplete-theme-classic"
/>

Algolia doesn’t provide support regarding third party services like jsDeliver or other CDNs.

Defining where to put your autocomplete

To get started, you need a container for your autocomplete to go in. If you don’t have one already, you can insert one into your markup:

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

Then, insert your autocomplete into it by calling the autocomplete function and providing the container. It can be a CSS selector or an Element.

Make sure to provide a container (for example, a div), not an input. Autocomplete generates a fully accessible search box for you.

1
2
3
4
5
6
7
8
9
10
11
import { autocomplete } from '@algolia/autocomplete-js';

import '@algolia/autocomplete-theme-classic';

autocomplete({
  container: '#autocomplete',
  placeholder: 'Search for products',
  getSources() {
    return [];
  },
});

You may have noticed two new options: placeholder and getSources. The placeholder option defines the placeholder text to show until the user starts typing in the input.

Autocomplete is now plugged in. But you won’t see anything appear until you define your sources.

Defining what items to display

Sources define where to retrieve the items to display in your autocomplete dropdown. You define your sources in the getSources function by returning an array of source objects.

Each source object needs to include a sourceId and a getItems function that returns the items to display. Sources can be static or dynamic.

This example uses an Algolia index of ecommerce products as a source. The autocomplete-js package provides a built-in getAlgoliaResults function for just this purpose.

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

import '@algolia/autocomplete-theme-classic';

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

autocomplete({
  container: '#autocomplete',
  placeholder: 'Search for products',
  getSources({ query }) {
    return [
      {
        sourceId: 'products',
        getItems() {
          return getAlgoliaResults({
            searchClient,
            queries: [
              {
                indexName: 'instant_search',
                query,
                params: {
                  hitsPerPage: 5,
                },
              },
            ],
          });
        },
        // ...
      },
    ];
  },
});

The getAlgoliaResults function requires an Algolia search client initialized with an Algolia application ID and API key. It lets you search into your Algolia index using an array of queries, which defines one or more queries to send to the index.

This example makes just one query to the “autocomplete” index using the query from getSources. For now, it passes one additional parameter, hitsPerPage to define how many items to display, but you could pass any other Algolia query parameters.

Although you’ve now declared what items to display using getSources, you still won’t see anything until you’ve defined how to display the items you’ve retrieved.

Defining how to display items

Sources also define how to display items in your Autocomplete using templates. Templates can return a string or anything that’s a valid Virtual DOM element. The example creates a Preact component called ProductItem to use as the template for each item.

The given classNames correspond to the classic theme imported earlier.

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
/** @jsx h */
import { autocomplete, getAlgoliaResults } from '@algolia/autocomplete-js';
import algoliasearch from 'algoliasearch';
import { h, Fragment } from 'preact';

import '@algolia/autocomplete-theme-classic';

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

autocomplete({
  container: '#autocomplete',
  placeholder: 'Search for products',
  getSources({ query }) {
    return [
      {
        sourceId: 'products',
        getItems() {
          return getAlgoliaResults({
            searchClient,
            queries: [
              {
                indexName: 'instant_search',
                query,
                params: {
                  hitsPerPage: 5,
                  attributesToSnippet: ['name:10', 'description:35'],
                  snippetEllipsisText: '',
                },
              },
            ],
          });
        },
        templates: {
          item({ item, components }) {
            return <ProductItem hit={item} components={components} />;
          },
        },
      },
    ];
  },
});

function ProductItem({ hit, components }: ProductItemProps) {
  return (
    <div className="aa-ItemWrapper">
      <div className="aa-ItemContent">
        <div className="aa-ItemIcon aa-ItemIcon--alignTop">
          <img src={hit.image} alt={hit.name} width="40" height="40" />
        </div>
        <div className="aa-ItemContentBody">
          <div className="aa-ItemContentTitle">
            <components.Snippet hit={hit} attribute="name" />
          </div>
          <div className="aa-ItemContentDescription">
            <components.Snippet hit={hit} attribute="description" />
          </div>
        </div>
        <div className="aa-ItemActions">
          <button
            className="aa-ItemActionButton aa-DesktopOnly aa-ActiveOnly"
            type="button"
            title="Select"
          >
            <svg viewBox="0 0 24 24" width="20" height="20" fill="currentColor">
              <path d="M18.984 6.984h2.016v6h-15.188l3.609 3.609-1.406 1.406-6-6 6-6 1.406 1.406-3.609 3.609h13.172v-4.031z" />
            </svg>
          </button>
          <button
            className="aa-ItemActionButton"
            type="button"
            title="Add to cart"
          >
            <svg viewBox="0 0 24 24" width="18" height="18" fill="currentColor">
              <path d="M19 5h-14l1.5-2h11zM21.794 5.392l-2.994-3.992c-0.196-0.261-0.494-0.399-0.8-0.4h-12c-0.326 0-0.616 0.156-0.8 0.4l-2.994 3.992c-0.043 0.056-0.081 0.117-0.111 0.182-0.065 0.137-0.096 0.283-0.095 0.426v14c0 0.828 0.337 1.58 0.879 2.121s1.293 0.879 2.121 0.879h14c0.828 0 1.58-0.337 2.121-0.879s0.879-1.293 0.879-2.121v-14c0-0.219-0.071-0.422-0.189-0.585-0.004-0.005-0.007-0.010-0.011-0.015zM4 7h16v13c0 0.276-0.111 0.525-0.293 0.707s-0.431 0.293-0.707 0.293h-14c-0.276 0-0.525-0.111-0.707-0.293s-0.293-0.431-0.293-0.707zM15 10c0 0.829-0.335 1.577-0.879 2.121s-1.292 0.879-2.121 0.879-1.577-0.335-2.121-0.879-0.879-1.292-0.879-2.121c0-0.552-0.448-1-1-1s-1 0.448-1 1c0 1.38 0.561 2.632 1.464 3.536s2.156 1.464 3.536 1.464 2.632-0.561 3.536-1.464 1.464-2.156 1.464-3.536c0-0.552-0.448-1-1-1s-1 0.448-1 1z" />
            </svg>
          </button>
        </div>
      </div>
    </div>
  );
}

The ProductItem component uses the Snippet component to only display part of the item’s name and description, if they go beyond a certain length. Each attribute’s allowed length and the characters to show when truncated are defined in the attributesToSnippet and snippetEllipsisText Algolia query parameters in params.

This is what the truncated JSON record looks like:

1
2
3
4
5
6
7
{
  "name": "Apple - MacBook Air® (Latest Model) - 13.3\" Display - Intel Core i5 - 4GB Memory - 128GB Flash Storage - Silver",
  "description": "MacBook Air features fifth-generation Intel Core processors with stunning graphics, all-day battery life*, ultrafast flash storage, and great built-in apps. It's thin, light and durable enough to take everywhere you go &#8212; and powerful enough to do everything once you get there.",
  "image": "https://cdn-demo.algolia.com/bestbuy/1581921_sb.jpg",
  "url": "http://www.bestbuy.com/site/apple-macbook-air-latest-model-13-3-display-intel-core-i5-4gb-memory-128gb-flash-storage-silver/1581921.p?id=1219056464137&skuId=1581921&cmp=RMX&ky=1uWSHMdQqBeVJB9cXgEke60s5EjfS6M1W",
  "objectID": "1581921"
}

Check out how the template displays items by searching in the input below:

Keeping the panel open during development

When you’re building, styling, or debugging your autocomplete experience, you might want to inspect it in your web developer tools. You can set the debug option to true to keep the panel open when inspecting it.

You should only use the debug option during development.

Going further

This is all you need for a basic implementation. To go further, you can use the getItemUrl to add keyboard accessibility features. It lets users open items directly from the autocomplete menu.

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

import '@algolia/autocomplete-theme-classic';

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

autocomplete({
  container: '#autocomplete',
  placeholder: 'Search for products',
  getSources({ query }) {
    return [
      {
        sourceId: 'products',
        getItems() {
          // ...
        },
        templates: {
          // ...
        },
        getItemUrl({ item }) {
          return item.url;
        },
      },
    ];
  },
});

function ProductItem({ hit, breadcrumb }) {
  // ...
}

Now give it a try: navigate to one of the items using your keyboard and hit Enter. This brings you to the product detail page on bestbuy.com.

This outlines a basic autocomplete implementation. There’s a lot more you can do like:

To learn about customization options, read the Core Concepts or follow one of the Guides.

Did you find this page helpful?