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

# Include multiple result types

> Learn how to show different types of results in one autocomplete.

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>

Query suggestions are one aspect of rich multi-category search experiences.
For example, if you search for something in your email inbox,
your results could contain not just email threads, but also contacts, attachments, and more.
Ecommerce stores often show query suggestions, products, blog posts, brands, and categories all in one autocomplete.

It's best to display different results types in different sections.
This helps users understand what the items are and what happens when they choose one.

The Autocomplete library lets you mix different item types in one autocomplete and customize their display.
To do so you need to several sources in the [`getSources`](/doc/ui-libraries/autocomplete/core-concepts/sources) option.
This tutorial outlines how to combine [static predefined items](/doc/ui-libraries/autocomplete/core-concepts/sources#static-sources), [recent searches](/doc/ui-libraries/autocomplete/guides/adding-recent-searches) and [Query Suggestions](/doc/ui-libraries/autocomplete/guides/adding-suggested-searches).

Using [plugins](/doc/ui-libraries/autocomplete/core-concepts/plugins) for each source makes the code modular, reusable, and sharable.
However, instead of using plugins, you could add different sources directly in `getSources`.

## 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 />.

## Starter code

Begin by adding the following Autocomplete starter code.
Create a file called `index.js` in your `src` directory.

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

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

This starter code assumes you want to insert the Autocomplete menu into a DOM element with `autocomplete` as an [`id`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/id).
Change 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). 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 create and add [plugins](/doc/ui-libraries/autocomplete/core-concepts/plugins) for predefined items, recent searches, and Query Suggestions next.

## Add predefined items

A popular search pattern for autocomplete menus shows predefined search terms as soon as a user clicks on the search box and before they begin typing anything.
This provides a guided experience and exposes users to helpful resources or other content you want them to see.

This tutorial describes how to create a [plugin](/doc/ui-libraries/autocomplete/core-concepts/plugins) to show static, predefined items.
In particular, it exposes helpful links users may want to refer to.

### Create a predefined items plugin

Begin by creating a `predefinedItemsPlugin.js` file in your `src` directory, with the following code:

```js JavaScript icon=code theme={"system"}
const predefinedItems = [
  {
    label: "Documentation",
    url: "https://www.algolia.com/doc/ui-libraries/autocomplete/introduction/what-is-autocomplete/",
  },
  {
    label: "GitHub",
    url: "https://github.com/algolia/autocomplete",
  },
];

export const predefinedItemsPlugin = {
  getSources() {
    return [
      {
        sourceId: "predefinedItemsPlugin",
        getItems({ query }) {
          if (!query) {
            return predefinedItems;
          }
          return predefinedItems.filter((item) =>
            item.label.toLowerCase().includes(query.toLowerCase()),
          );
        },
        getItemUrl({ item }) {
          return item.url;
        },
        templates: {
          // ...
        },
      },
    ];
  },
};
```

The `predefinedItemsPlugin` plugin has a similar signature as any other autocomplete implementation:
it uses the [`getSources`](/doc/ui-libraries/autocomplete/api-reference/autocomplete-js/autocomplete#param-get-sources) option to return an array of items to display.
Each object in the array defines where to get items using [`getItems`](/doc/ui-libraries/autocomplete/core-concepts/sources#param-get-items).
An Autocomplete plugin is an object that implements the `AutocompletePlugin` interface.
For more information, see [Building your own plugin](/doc/ui-libraries/autocomplete/core-concepts/plugins#build-your-own-plugin).

In this example, `getItems` returns a filtered array of `predefinedItems`.
The code filters the array to return items that match the query, if it exists.
If it doesn't, it returns the entire array.
**You can return whatever predefined items you like and format them accordingly**.

For example, suppose you want to show trending search items instead of helpful links.
Use `getItems` to retrieve them from another source,
[including an asynchronous API](/doc/ui-libraries/autocomplete/core-concepts/sources#dynamic-sources).

The [`getItemUrl`](/doc/ui-libraries/autocomplete/core-concepts/sources#param-get-item-url) function defines how to get the URL of an item.
In this case, since it's an attribute on each object in the `predefinedItems` array, just return the attribute.
Use `getItemUrl` to add [keyboard navigation](/doc/ui-libraries/autocomplete/core-concepts/keyboard-navigation) to the autocomplete menu.
Users can scroll through items in the  menu with the up and down keys.
When they hit Enter on one of the `predefinedItems` or any source that includes `getItemUrl`, it opens the URL retrieved from `getItemUrl`.

Templates define how to display each section of the autocomplete, including the [`header`](/doc/ui-libraries/autocomplete/core-concepts/templates#param-templates-header), [`footer`](/doc/ui-libraries/autocomplete/core-concepts/templates#param-templates-footer), and each [`item`](/doc/ui-libraries/autocomplete/core-concepts/templates#param-templates-item).
Templates can return any valid virtual DOM element.

This example defines how to display each predefined item with the `item` template and gives a `header` for the entire section.

<CodeGroup>
  ```js JavaScript theme={"system"}
  // ...

  export const predefinedItemsPlugin = {
    getSources() {
      return [
        {
          sourceId: "predefinedItemsPlugin",
          getItems({ query }) {
            if (!query) {
              return predefinedItems;
            }
            return predefinedItems.filter((item) =>
              item.label.toLowerCase().includes(query.toLowerCase()),
            );
          },
          getItemUrl({ item }) {
            return item.url;
          },
          templates: {
            header({ items, html }) {
              if (items.length === 0) {
                return null;
              }

              return html`<span class="aa-SourceHeaderTitle">Links</span>
                <div class="aa-SourceHeaderLine" />`;
            },
            item({ item, html }) {
              return html`<a class="aa-ItemLink" href="${item.url}">
                <div class="aa-ItemIcon aa-ItemIcon--noBorder">
                  <svg
                    width="18"
                    height="18"
                    viewBox="0 0 24 24"
                    fill="none"
                    stroke="currentColor"
                    stroke-width="2"
                    stroke-linecap="round"
                    stroke-linejoin="round"
                  >
                    <path
                      d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"
                    />
                    <polyline points="15 3 21 3 21 9" />
                    <line x1="10" y1="14" x2="21" y2="3" />
                  </svg>
                </div>
                <div class="aa-ItemContent">
                  <div class="aa-ItemContentTitle">${item.label}</div>
                </div>
              </a>`;
            },
          },
        },
      ];
    },
  };
  ```

  ```jsx JSX theme={"system"}
  // ...

  export const predefinedItemsPlugin = {
    getSources() {
      return [
        {
          sourceId: "predefinedItemsPlugin",
          getItems({ query }) {
            if (!query) {
              return predefinedItems;
            }
            return predefinedItems.filter((item) =>
              item.label.toLowerCase().includes(query.toLowerCase()),
            );
          },
          getItemUrl({ item }) {
            return item.url;
          },
          templates: {
            header({ items }) {
              if (items.length === 0) {
                return null;
              }

              return (
                <>
                  <span className="aa-SourceHeaderTitle">Links</span>
                  <div className="aa-SourceHeaderLine" />
                </>
              );
            },
            item({ item }) {
              return (
                <a className="aa-ItemLink" href={item.url}>
                  <div className="aa-ItemIcon aa-ItemIcon--noBorder">
                    <svg
                      width="18"
                      height="18"
                      viewBox="0 0 24 24"
                      fill="none"
                      stroke="currentColor"
                      strokeWidth="2"
                      strokeLinecap="round"
                      strokeLinejoin="round"
                    >
                      <path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" />
                      <polyline points="15 3 21 3 21 9" />
                      <line x1="10" y1="14" x2="21" y2="3" />
                    </svg>
                  </div>
                  <div className="aa-ItemContent">
                    <div className="aa-ItemContentTitle">{item.label}</div>
                  </div>
                </a>
              );
            },
          },
        },
      ];
    },
  };
  ```
</CodeGroup>

### Add the predefined items plugin to the autocomplete

Import the newly created `predefinedItemsPlugin` and add it to`plugins` in `index.js`.
Once you've done that, the file should look like this:

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

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

Now, as soon as a user clicks on the search box, these predefined items appear.
Once they begin typing, only predefined items that contain the query remain.

## Add recent searches and Query Suggestions

You can add [recent searches](/doc/ui-libraries/autocomplete/guides/adding-recent-searches) and [Query Suggestions](/doc/ui-libraries/autocomplete/guides/adding-suggested-searches) using out-of-the-box plugins.

### Create a recent searches plugin

Use the out-of-the-box [`createLocalStorageRecentSearchesPlugin`](/doc/ui-libraries/autocomplete/api-reference/autocomplete-plugin-recent-searches/createLocalStorageRecentSearchesPlugin) function to create a recent searches plugin:

```js JavaScript icon=code theme={"system"}
import { createLocalStorageRecentSearchesPlugin } from "@algolia/autocomplete-plugin-recent-searches";

const recentSearchesPlugin = createLocalStorageRecentSearchesPlugin({
  key: "RECENT_SEARCH",
  limit: 5,
});
```

The `key` can be any string and is required to differentiate search histories if you have several Autocomplete experiences on one page.
The `limit` defines the maximum number of recent searches to display.

### Create a Query Suggestions plugin

<Note>
  If you don't have a Query Suggestions index yet, [create one](/doc/guides/building-search-ui/ui-and-ux-patterns/query-suggestions/js).
  Use the demo app credentials and index name provided in this tutorial.
</Note>

Use the out-of-the-box [`createQuerySuggestionsPlugin`](/doc/ui-libraries/autocomplete/api-reference/autocomplete-plugin-query-suggestions/createQuerySuggestionsPlugin) function to create a Query Suggestions plugin.
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 index.

```js JavaScript icon=code theme={"system"}
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",
});
```

### Coordinate Query Suggestions with other sources

When instantiating your Query Suggestions plugin, you can optionally pass a [`getSearchParams`](/doc/ui-libraries/autocomplete/api-reference/autocomplete-plugin-query-suggestions/createQuerySuggestionsPlugin#param-get-search-params) function to apply [Algolia query parameters](/doc/api-reference/api-parameters) to the suggestions returned from the plugin.
This is helpful if you need to coordinate your Query Suggestions with other sections displayed in the autocomplete,
like [recent searches](/doc/ui-libraries/autocomplete/guides/adding-recent-searches).

For example, if you'd like to show a combined total of 10 search terms (recent searches plus Query Suggestions),
you can indicate this:

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

const recentSearchesPlugin = createLocalStorageRecentSearchesPlugin({
  key: "RECENT_SEARCH",
  limit: 5,
});

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

const querySuggestionsPlugin = createQuerySuggestionsPlugin({
  searchClient,
  indexName: "instant_search_demo_query_suggestions",
  getSearchParams() {
    return recentSearchesPlugin.data.getAlgoliaSearchParams({
      hitsPerPage: 10,
    });
  },
});

autocomplete({
  // ...
});
```

This shows up to five recent searches (set by the [`limit`](/doc/ui-libraries/autocomplete/api-reference/autocomplete-plugin-recent-searches/createLocalStorageRecentSearchesPlugin#param-limit) parameter) and up to 10 total search terms.
If there's only one recent search in local storage,
the autocomplete displays nine Query Suggestions, assuming that there are nine relevant suggestions.

### Separate result types

When using sources other than just recent and suggested searches, it's best to label the different result types with [`headers`](/doc/ui-libraries/autocomplete/core-concepts/templates#param-templates-header).
For the `createLocalStorageRecentSearchesPlugin` and `createQuerySuggestionsPlugin` plugins,
use the [`transformSource`](/doc/ui-libraries/autocomplete/api-reference/autocomplete-plugin-query-suggestions/createQuerySuggestionsPlugin#param-transform-source) option to do this.

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

  // ...

  const recentSearchesPlugin = createLocalStorageRecentSearchesPlugin({
    // ...
    transformSource({ source }) {
      return {
        ...source,
        templates: {
          ...source.templates,
          header({ items, html }) {
            if (items.length === 0) {
              return null;
            }

            return html`<span class="aa-SourceHeaderTitle">Recent</span>
              <div class="aa-SourceHeaderLine" />`;
          },
        },
      };
    },
  });

  const querySuggestionsPlugin = createQuerySuggestionsPlugin({
    // ...
    transformSource({ source }) {
      return {
        ...source,
        templates: {
          ...source.templates,
          header({ items, html }) {
            if (items.length === 0) {
              return null;
            }

            return html`<span class="aa-SourceHeaderTitle">Suggestions</span>
              <div class="aa-SourceHeaderLine" />`;
          },
        },
      };
    },
  });

  autocomplete({
    // ...
  });
  ```

  ```jsx JSX theme={"system"}
  import { autocomplete } from "@algolia/autocomplete-js";
  import { createLocalStorageRecentSearchesPlugin } from "@algolia/autocomplete-plugin-recent-searches";
  import { createQuerySuggestionsPlugin } from "@algolia/autocomplete-plugin-query-suggestions";

  // ...

  const recentSearchesPlugin = createLocalStorageRecentSearchesPlugin({
    // ...
    transformSource({ source }) {
      return {
        ...source,
        templates: {
          ...source.templates,
          header({ items }) {
            if (items.length === 0) {
              return null;
            }

            return (
              <>
                <span className="aa-SourceHeaderTitle">Recent</span>
                <div className="aa-SourceHeaderLine" />
              </>
            );
          },
        },
      };
    },
  });

  const querySuggestionsPlugin = createQuerySuggestionsPlugin({
    // ...
    transformSource({ source }) {
      return {
        ...source,
        templates: {
          ...source.templates,
          header({ items }) {
            if (items.length === 0) {
              return null;
            }

            return (
              <>
                <span className="aa-SourceHeaderTitle">Suggestions</span>
                <div className="aa-SourceHeaderLine" />
              </>
            );
          },
        },
      };
    },
  });

  autocomplete({
    // ...
  });
  ```
</CodeGroup>

## Add plugins

All that's left to do is add all your plugins to your Autocomplete instance:

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

const recentSearchesPlugin = createLocalStorageRecentSearchesPlugin({
  key: "RECENT_SEARCH",
  limit: 5,
});

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

const querySuggestionsPlugin = createQuerySuggestionsPlugin({
  searchClient,
  indexName: "instant_search_demo_query_suggestions",
  getSearchParams() {
    return recentSearchesPlugin.data.getAlgoliaSearchParams({
      hitsPerPage: 10,
    });
  },
});

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

This creates a basic multi-source autocomplete.

## Next steps

This tutorial combined three sources in one autocomplete.
Depending on your use case, you might want to add more or different ones than the ones included here.
Regardless of what you use for your sections, the method is the same:
provide a different a [source](/doc/ui-libraries/autocomplete/core-concepts/sources) for each.

You may also choose to style your multi-source autocomplete differently by creating a horizontal layout or further differentiating how to display each source type.
