> ## Documentation Index
> Fetch the complete documentation index at: https://algolia.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Build a Query Suggestions UI with Autocomplete

> Learn how to include suggested searches using the Query Suggestions plugin.

export const Records = () => <Tooltip tip="A record is a searchable object in an Algolia index. Each record consists of named attributes." cta="Algolia records" href="/doc/guides/sending-and-managing-data/prepare-your-data#algolia-records">
    records
  </Tooltip>;

export const Index = () => <Tooltip tip="An Algolia index is a searchable dataset that consists of records and configuration settings. These settings define how the records are searched and ranked.">
    index
  </Tooltip>;

export const Application = () => <Tooltip tip="An Algolia application is a self-contained environment with its own indices, configuration, and API keys. Applications don't share data or settings with each other.">
    application
  </Tooltip>;

<Tip>
  Autocomplete is also available as an experimental widget in InstantSearch,
  making it easier to integrate into your search experience.
  For more information,
  see the API reference for [InstantSearch.js](/doc/api-reference/widgets/autocomplete/js) or
  [React InstantSearch](/doc/api-reference/widgets/autocomplete/react).
</Tip>

The most common Autocomplete UX is one that displays a list of suggested searches that your users can select from as they type.
Algolia provides a Query Suggestions feature that generates suggested search terms [based on your what your users are searching for and the results within your data](/doc/guides/building-search-ui/ui-and-ux-patterns/query-suggestions/js#how-query-suggestions-work).

This tutorial explains how to integrate Algolia Query Suggestions into an Autocomplete menu using the [`autocomplete-plugin-query-suggestions`](/doc/ui-libraries/autocomplete/api-reference/autocomplete-plugin-query-suggestions) package.

## Before you begin

This guide assumes that you know HTML, CSS, and JavaScript and that you have existing HTML with an input element where you want to insert the autocomplete drop-down menu.

It also assumes that you have an Algolia <Application /> with a populated [Query Suggestions](/doc/guides/building-search-ui/ui-and-ux-patterns/query-suggestions/js) <Index />.

<Tip>
  For learning purposes, use the demo application credentials and index provided in this tutorial.
</Tip>

## Get started

Create an `index.js` file in your `src` directory, and add the following code:

```js JavaScript icon=code theme={"system"}
// index.js
import { autocomplete } from "@algolia/autocomplete-js";

autocomplete({
  container: "#autocomplete",
  plugins: [],
  openOnFocus: true,
});
```

This code adds Autocomplete to a DOM element with `autocomplete` as `id`.
Update the [`container`](/doc/ui-libraries/autocomplete/api-reference/autocomplete-js/autocomplete#param-container) to [match your markup](/doc/ui-libraries/autocomplete/core-concepts/basic-configuration-options) parameter to match your HTML.
Setting [`openOnFocus`](/doc/ui-libraries/autocomplete/api-reference/autocomplete-js/autocomplete#param-open-on-focus) to `true` ensures that the drop-down menu appears as soon as a user focuses the input.

For now, `plugins` is an empty array, but you'll learn how to add the Query Suggestions [plugin](/doc/ui-libraries/autocomplete/core-concepts/plugins) next.

## Add Query Suggestions

The [`autocomplete-plugin-query-suggestions`](/doc/ui-libraries/autocomplete/api-reference/autocomplete-plugin-query-suggestions) package provides the [`createQuerySuggestionsPlugin`](/doc/ui-libraries/autocomplete/api-reference/autocomplete-plugin-query-suggestions/createQuerySuggestionsPlugin) function for creating a Query Suggestions [plugin](/doc/ui-libraries/autocomplete/core-concepts/plugins) out-of-the-box.

It requires an [Algolia search client](/doc/libraries/sdk/install)
initialized with an [Algolia application ID and API key](/doc/guides/sending-and-managing-data/send-and-update-your-data/how-to/importing-with-the-api#required-credentials) and an `indexName`.
The `indexName` is the name of your [Query Suggestions](/doc/guides/building-search-ui/ui-and-ux-patterns/query-suggestions/js) index.

```js JavaScript icon=code theme={"system"}
// index.js
import { autocomplete } from "@algolia/autocomplete-js";
import { createQuerySuggestionsPlugin } from "@algolia/autocomplete-plugin-query-suggestions";

const appId = "latency";
const apiKey = "6be0576ff61c053d5f9a3225e2a90f76";
const searchClient = algoliasearch(appId, apiKey);

const querySuggestionsPlugin = createQuerySuggestionsPlugin({
  searchClient,
  indexName: "instant_search_demo_query_suggestions",
});

autocomplete({
  container: "#autocomplete",
  plugins: [querySuggestionsPlugin],
  openOnFocus: true,
});
```

You can optionally pass a `getSearchParams` function to apply [Algolia query parameters](/doc/api-reference/api-parameters) to the suggestions returned from the plugin.

For example, you may choose to display 10 Query Suggestions if users haven't typed anything yet, but only five if they have:

```js JavaScript icon=code theme={"system"}
import { autocomplete } from "@algolia/autocomplete-js";
import { createQuerySuggestionsPlugin } from "@algolia/autocomplete-plugin-query-suggestions";

const appId = "latency";
const apiKey = "6be0576ff61c053d5f9a3225e2a90f76";
const searchClient = algoliasearch(appId, apiKey);

const querySuggestionsPlugin = createQuerySuggestionsPlugin({
  searchClient,
  indexName: "instant_search_demo_query_suggestions",
  getSearchParams({ state }) {
    return { hitsPerPage: state.query ? 5 : 10 };
  },
});

autocomplete({
  container: "#autocomplete",
  plugins: [querySuggestionsPlugin],
  openOnFocus: true,
});
```

This option can be especially useful if you are [displaying other sources](/doc/ui-libraries/autocomplete/guides/including-multiple-result-types) along with Query Suggestions and want to always show the same total number of items or otherwise align your query parameters.

## Add categories

Displaying relevant categories, along with suggestions,
is helpful since it lets users limit their search scope.
When a user selects a suggestion with a category,
you can use both the suggestion and the associated category to show only the most relevant results.
This lets users skip the additional task of selecting a category once they're on the results page.
By including categories in your suggestions,
you enable users to land on the most relevant set of results with as little friction as possible.

With [some configuration](/doc/guides/building-search-ui/ui-and-ux-patterns/query-suggestions/js),
the Algolia [Query Suggestions](/doc/guides/building-search-ui/ui-and-ux-patterns/query-suggestions/js) feature adds relevant categories to suggestion <Records />.
Refer to the [index schema](/doc/guides/building-search-ui/ui-and-ux-patterns/query-suggestions/js#query-suggestions-index-schema) to see how the feature stores information about each suggestion record.

To display categories with the suggestions,
you need to define the attribute to retrieve category information from,
using the `categoryAttribute` option when instantiating the plugin.

In this example, the category data is stored in the nested attribute `instant_search.facets.exact_matches.categories`.
With this structure, you need to provide the path `["instant_search", "facets", "exact_matches", "categories"]`
as the `categoryAttribute`.

You can also set the number of items to display categories for using `itemsWithCategories` and the maximum number of categories to display per item using `categoriesPerItem`.
Both default to `1`.

```js JavaScript icon=code theme={"system"}
import { autocomplete } from "@algolia/autocomplete-js";
import { createQuerySuggestionsPlugin } from "@algolia/autocomplete-plugin-query-suggestions";

const appId = "latency";
const apiKey = "6be0576ff61c053d5f9a3225e2a90f76";
const searchClient = algoliasearch(appId, apiKey);

const querySuggestionsPlugin = createQuerySuggestionsPlugin({
  searchClient,
  indexName: "instant_search_demo_query_suggestions",
  getSearchParams({ state }) {
    return { hitsPerPage: state.query ? 5 : 10 };
  },
  categoryAttribute: [
    "instant_search",
    "facets",
    "exact_matches",
    "categories",
  ],
  itemsWithCategories: 2,
  categoriesPerItem: 2,
});

autocomplete({
  container: "#autocomplete",
  plugins: [querySuggestionsPlugin],
  openOnFocus: true,
});
```

### Apply categories

Now that the autocomplete displays categories on suggestions,
you need to apply them to the search results when a user selects a suggestion.

#### On the same page

If the search results are on the same page as the autocomplete,
you can use the [`onSelect`](/doc/ui-libraries/autocomplete/core-concepts/sources#param-on-select) hook to refine the search results.
You can access this hook within [`transformSource`](/doc/ui-libraries/autocomplete/api-reference/autocomplete-plugin-query-suggestions/createQuerySuggestionsPlugin#param-transform-source).
The function includes the original `source`, which you should return along with any options you want to add or overwrite.

```js JavaScript icon=code theme={"system"}
import { autocomplete } from "@algolia/autocomplete-js";
import { createQuerySuggestionsPlugin } from "@algolia/autocomplete-plugin-query-suggestions";

const appId = "latency";
const apiKey = "6be0576ff61c053d5f9a3225e2a90f76";
const searchClient = algoliasearch(appId, apiKey);

const querySuggestionsPlugin = createQuerySuggestionsPlugin({
  // ...
  transformSource({ source }) {
    return {
      ...source,
      onSelect({ item }) {
        // Assuming the `setSearchState` function updates the search page state.
        setSearchState({
          query: item.query,
          category: item.__autocomplete_qsCategory,
        });
      },
    };
  },
});

autocomplete({
  container: "#autocomplete",
  plugins: [querySuggestionsPlugin],
  openOnFocus: true,
});
```

#### On a linked search results page

If your autocomplete links to a separate search results page and you'd like to apply selected categories there, you can modify the results page URL with query parameters.

This example writes a `createUrl` function within [`transformSource`](/doc/ui-libraries/autocomplete/api-reference/autocomplete-plugin-query-suggestions/createQuerySuggestionsPlugin#param-transform-source) to do so.
It uses an item's `__autocomplete_qsCategory` property to construct the appropriate query parameters.
It then uses the function within the [`item` template](/doc/ui-libraries/autocomplete/core-concepts/templates#param-templates-item) and in [`getItemUrl`](/doc/ui-libraries/autocomplete/core-concepts/sources#param-get-item-url).
This way, whether users click a link or use keyboard navigation, they land on a search results page with categories applied.

<CodeGroup>
  ```js JavaScript theme={"system"}
  import { autocomplete } from "@algolia/autocomplete-js";
  import { createQuerySuggestionsPlugin } from "@algolia/autocomplete-plugin-query-suggestions";

  const appId = "latency";
  const apiKey = "6be0576ff61c053d5f9a3225e2a90f76";
  const searchClient = algoliasearch(appId, apiKey);

  const querySuggestionsPlugin = createQuerySuggestionsPlugin({
    // ...
    transformSource({ source }) {
      function createUrl(item) {
        const urlParams = new URLSearchParams();
        urlParams.set("q", item.query);
        if (item.__autocomplete_qsCategory) {
          urlParams.set("category", item.__autocomplete_qsCategory);
        }

        return `/search?${urlParams.toString()}`;
      }

      return {
        ...source,
        getItemUrl({ item }) {
          return createUrl(item);
        },
        templates: {
          item(params) {
            const { item, html } = params;

            return html`<a class="aa-ItemLink" href="${createUrl(item)}">
              ${source.templates.item(params).props.children}
            </a>`;
          },
        },
      };
    },
  });

  autocomplete({
    container: "#autocomplete",
    plugins: [querySuggestionsPlugin],
    openOnFocus: true,
  });
  ```

  ```jsx JSX theme={"system"}
  /** @jsx h */
  import { h } from "preact";
  import { autocomplete } from "@algolia/autocomplete-js";
  import { createQuerySuggestionsPlugin } from "@algolia/autocomplete-plugin-query-suggestions";

  const appId = "latency";
  const apiKey = "6be0576ff61c053d5f9a3225e2a90f76";
  const searchClient = algoliasearch(appId, apiKey);

  const querySuggestionsPlugin = createQuerySuggestionsPlugin({
    // ...
    transformSource({ source }) {
      function createUrl(item) {
        const urlParams = new URLSearchParams();
        urlParams.set("q", item.query);
        if (item.__autocomplete_qsCategory) {
          urlParams.set("category", item.__autocomplete_qsCategory);
        }

        return `/search?${urlParams.toString()}`;
      }

      return {
        ...source,
        getItemUrl({ item }) {
          return createUrl(item);
        },
        templates: {
          item(params) {
            const { item } = params;

            return (
              <a className="aa-ItemLink" href={createUrl(item)}>
                {source.templates.item(params).props.children}
              </a>
            );
          },
        },
      };
    },
  });

  autocomplete({
    container: "#autocomplete",
    plugins: [querySuggestionsPlugin],
    openOnFocus: true,
  });
  ```
</CodeGroup>

## Customize Query Suggestions

The [`createQuerySuggestionsPlugin`](/doc/ui-libraries/autocomplete/api-reference/autocomplete-plugin-query-suggestions/createQuerySuggestionsPlugin) creates a functional plugin out of the box. You may want to customize some aspects of it, depending on your use case. To change [`templates`](/doc/ui-libraries/autocomplete/core-concepts/templates) or other [source](/doc/ui-libraries/autocomplete/core-concepts/sources) configuration options, you can use [`transformSource`](/doc/ui-libraries/autocomplete/api-reference/autocomplete-plugin-query-suggestions/createQuerySuggestionsPlugin#param-transform-source). The function includes the original `source`, which you should return along with any options you want to add or overwrite.

For example, if you use Autocomplete as an entry point to a search results page,
you can turn Query Suggestions into links by modifying [`getItemUrl`](/doc/ui-libraries/autocomplete/core-concepts/sources#param-get-item-url) and the [`item`](/doc/ui-libraries/autocomplete/core-concepts/templates#param-templates-item) template.

<CodeGroup>
  ```js JavaScript theme={"system"}
  const querySuggestionsPlugin = createQuerySuggestionsPlugin({
    // ...
    transformSource({ source }) {
      return {
        ...source,
        getItemUrl({ item }) {
          return `/search?q=${item.query}`;
        },
        templates: {
          item(params) {
            const { item, html } = params;

            return html`<a class="aa-ItemLink" href="/search?q=${item.query}">
              ${source.templates.item(params).props.children}
            </a>`;
          },
        },
      };
    },
  });
  ```

  ```jsx JSX theme={"system"}
  const querySuggestionsPlugin = createQuerySuggestionsPlugin({
    // ...
    transformSource({ source }) {
      return {
        ...source,
        getItemUrl({ item }) {
          return `/search?q=${item.query}`;
        },
        templates: {
          item(params) {
            const { item } = params;

            return (
              <a className="aa-ItemLink" href={`/search?q=${item.query}`}>
                {source.templates.item(params).props.children}
              </a>
            );
          },
        },
      };
    },
  });
  ```
</CodeGroup>

If you use Autocomplete on the same page as your main search and want to avoid reloading the full page when an item is selected, you can modify your search query state when a user selects an item with [`onSelect`](/doc/ui-libraries/autocomplete/core-concepts/sources#param-on-select):

```js JavaScript icon=code theme={"system"}
const querySuggestionsPlugin = createQuerySuggestionsPlugin({
  // ...
  transformSource({ source }) {
    return {
      ...source,
      onSelect({ item }) {
        // Assuming the `setSearchState` function updates the search page state.
        setSearchState({ query: item.query });
      },
    };
  },
});
```

## Next steps

This tutorial focuses on adding Query Suggestions to an autocomplete menu.
Many autocomplete menus also include recent searches and possibly other items.

* [Recent searches](/doc/ui-libraries/autocomplete/guides/adding-recent-searches)
* [Multiple results types](/doc/ui-libraries/autocomplete/guides/including-multiple-result-types)
* [Static sources](/doc/ui-libraries/autocomplete/core-concepts/sources#static-sources)
