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

# Redirect searches to a URL

> Learn how to add redirects to your autocomplete experience with the redirect URL plugin.

export const SearchQuery = () => <Tooltip tip="The text users enter into a search box. In the Search API, this corresponds to the query parameter. A search query is often used with filters, facets, and other parameters, but these aren't part of the query text itself.">
    search query
  </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>

Redirects can enhance your autocomplete experience. For example:

* Searching for "help" redirects users to a support page
* Searching for a category, such as, "TV" redirects users to a category page
* Searching for a specific product or brand redirects users to a seasonal promotional page for it
* Searching for specific keywords related to an ongoing event, such as "masks",
  redirects users to a more specific landing page

This guide explains how to add redirects to Autocomplete using the redirect URL plugin.
You can use the plugin with Algolia and non-Algolia sources.

## Before you begin

Before adding redirects,
you need an [Algolia index](/doc/guides/sending-and-managing-data/send-and-update-your-data)
with data and an HTML file with a container element for the Autocomplete menu.

<Note>
  If you want to use redirects without further frontend development,
  set up [rules for redirects](/doc/guides/managing-results/rules/merchandising-and-promoting/how-to/redirects)
</Note>

## Create an autocomplete instance

First, create an autocomplete instance. Create a new file `index.js` with the following code:

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

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

This code adds the autocomplete to a DOM element with the `id` attribute `autocomplete`.
You can use a different selector by changing the [`container`](/doc/ui-libraries/autocomplete/api-reference/autocomplete-js/autocomplete#param-container) parameter.
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.

## Add the redirect plugin to Algolia sources

To add the redirect plugin to Autocomplete,
install the [`autocomplete-plugin-redirect-url`](/doc/ui-libraries/autocomplete/api-reference/autocomplete-plugin-redirect-url) package.
To create the plugin, call the `createRedirectUrlPlugin` function, and add it to the list of plugins.

If you're using this plugin for an Algolia source with Rules with redirects as consequences,
you must have a source defined with [`getSources`](/doc/ui-libraries/autocomplete/core-concepts/sources#param-get-sources).
The source must have these properties:

* [`sourceId`](/doc/ui-libraries/autocomplete/core-concepts/sources#param-source-id)
* [`templates`](/doc/ui-libraries/autocomplete/core-concepts/templates)
* [`getItemInputValue`](/doc/ui-libraries/autocomplete/core-concepts/sources#param-get-item-input-value)
* [`getItems`](/doc/ui-libraries/autocomplete/core-concepts/sources#param-get-items)

See the following code for a complete example:

<CodeGroup>
  ```js JavaScript theme={"system"}
  import { autocomplete, getAlgoliaResults } from "@algolia/autocomplete-js";
  import { createRedirectUrlPlugin } from "@algolia/autocomplete-plugin-redirect-url";
  import { liteClient as algoliasearch } from "algoliasearch/lite";

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

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

  autocomplete({
    container: "#autocomplete",
    openOnFocus: true,
    plugins: [redirectUrlPlugin],
    getSources({ query }) {
      return [
        {
          sourceId: "demo-source",
          templates: {
            item(params) {
              const { item, html } = params;
              return html`<a class="aa-ItemLink">${item.name}</a>`;
            },
          },
          getItemInputValue({ item }) {
            return item.name;
          },
          getItems() {
            return getAlgoliaResults({
              searchClient,
              queries: [
                {
                  indexName: "instant_search",
                  params: {
                    query,
                    // the rules configured for this demo require this context to prevent triggering in other plugin demos
                    ruleContexts: ["enable-redirect-url"],
                    hitsPerPage: 10,
                  },
                },
              ],
            });
          },
        },
      ];
    },
  });
  ```

  ```jsx JSX theme={"system"}
  import { autocomplete, getAlgoliaResults } from "@algolia/autocomplete-js";
  import { createRedirectUrlPlugin } from "@algolia/autocomplete-plugin-redirect-url";
  import { liteClient as algoliasearch } from "algoliasearch/lite";

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

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

  autocomplete({
    container: "#autocomplete",
    openOnFocus: true,
    plugins: [redirectUrlPlugin],
    getSources({ query }) {
      return [
        {
          sourceId: "demo-source",
          templates: {
            item(params) {
              const { item } = params;
              return <a class="aa-ItemLink">${item.name}</a>;
            },
          },
          getItemInputValue({ item }) {
            return item.name;
          },
          getItems() {
            return getAlgoliaResults({
              searchClient,
              queries: [
                {
                  indexName: "instant_search",
                  params: {
                    query,
                    // the rules configured for this demo require this context to prevent triggering in other plugin demos
                    ruleContexts: ["enable-redirect-url"],
                    hitsPerPage: 10,
                  },
                },
              ],
            });
          },
        },
      ];
    },
  });
  ```
</CodeGroup>

## Set up redirects with non-Algolia sources

If you want to use redirects that are defined in a non-Algolia source,
you can configure [`createRedirectUrlPlugin`](/doc/ui-libraries/autocomplete/api-reference/autocomplete-plugin-redirect-url/createRedirectUrlPlugin)
to customize the redirect response.

Use the [`transformResponse`](/doc/ui-libraries/autocomplete/api-reference/autocomplete-plugin-redirect-url/createRedirectUrlPlugin#param-transform-response)
parameter to map the response from the source to the redirect object that's used by the plugin.

<CodeGroup>
  ```js JavaScript theme={"system"}
  import { autocomplete } from "@algolia/autocomplete-js";
  import { createRedirectUrlPlugin } from "@algolia/autocomplete-plugin-redirect-url";

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

  function transformResponse(response) {
    // assumes your non-Algolia source provides redirect URLs this way
    return response.myRedirectData?.url;
  }

  const redirectUrlPlugin = createRedirectUrlPlugin({
    transformResponse,
  });

  autocomplete({
    container: "#autocomplete",
    openOnFocus: true,
    plugins: [redirectUrlPlugin],
    getSources({ query }) {
      return [
        {
          sourceId: "demo-source",
          templates: {
            item(params) {
              const { item, html } = params;
              return html`<a class="aa-ItemLink">${item.name}</a>`;
            },
          },
          getItemInputValue({ item }) {
            return item.name;
          },
          getItems() {
            return {}; // your custom results here...
          },
        },
      ];
    },
  });
  ```

  ```jsx JSX theme={"system"}
  import { autocomplete } from "@algolia/autocomplete-js";
  import { createRedirectUrlPlugin } from "@algolia/autocomplete-plugin-redirect-url";

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

  function transformResponse(response) {
    // assumes your non-Algolia source provides redirect URLs this way
    return response.myRedirectData?.url;
  }

  const redirectUrlPlugin = createRedirectUrlPlugin({
    transformResponse,
  });

  autocomplete({
    container: "#autocomplete",
    openOnFocus: true,
    plugins: [redirectUrlPlugin],
    getSources({ query }) {
      return [
        {
          sourceId: "demo-source",
          templates: {
            item(params) {
              const { item } = params;
              return <a class="aa-ItemLink">${item.name}</a>;
            },
          },
          getItemInputValue({ item }) {
            return item.name;
          },
          getItems() {
            return {}; // your custom results here...
          },
        },
      ];
    },
  });
  ```
</CodeGroup>

## Control the redirect behavior

It's possible to have multiple redirect URLs, since redirect criteria may occur for each source and their queries. In these cases, you might want to control which redirect URL is used.

By default, the first source with a redirect with its first <SearchQuery /> is the redirect.
You can change this behavior with the [`onRedirect`](/doc/ui-libraries/autocomplete/api-reference/autocomplete-plugin-redirect-url/createRedirectUrlPlugin#param-on-redirect) callback, which receives the `redirects` array. This array contains every detected redirect for a given query, collected either automatically for Rules with redirects as consequences or from [`transformResponse`](/doc/ui-libraries/autocomplete/api-reference/autocomplete-plugin-redirect-url/createRedirectUrlPlugin#param-transform-response). For example:

```js JavaScript icon=code theme={"system"}
[
  {
    sourceId: "my-source-with-one-query",
    urls: ["https://www.algolia.com"],
  },
  {
    sourceId: "my-source-with-two-queries",
    urls: ["https://www.algolia.com", "https://www.algolia.com/hello-world"],
  },
];
```

In this example, a query triggered three redirect URLs in the response which mapped into an array of URLs for each source.
In this scenario, **you can implement [`onRedirect`](/doc/ui-libraries/autocomplete/api-reference/autocomplete-plugin-redirect-url/createRedirectUrlPlugin#param-on-redirect) to select the URL to redirect to.**

The following example shows how to pass an object with options to the `onRedirect` callback.
The options include a `navigator` object, which handles the redirection to the provided URL.
For more information, see [Keyboard navigation](/doc/ui-libraries/autocomplete/core-concepts/keyboard-navigation).

<CodeGroup>
  ```js JavaScript theme={"system"}
  import { autocomplete } from "@algolia/autocomplete-js";
  import { createRedirectUrlPlugin } from "@algolia/autocomplete-plugin-redirect-url";

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

  function onRedirect(redirects, { event, navigator, state }) {
    const item = redirects.find(
      (r) => r.sourceId === "my-source-with-two-queries",
    );
    const itemUrl = item?.urls?.find((url) =>
      url.startsWith("https://www.algolia.com"),
    );

    if (!itemUrl) {
      return;
    }

    if (event.metaKey || event.ctrlKey) {
      navigator.navigateNewTab({ itemUrl, item, state });
    } else if (event.shiftKey) {
      navigator.navigateNewWindow({ itemUrl, item, state });
    } else {
      navigator.navigate({ itemUrl, item, state });
    }
  }

  const redirectUrlPlugin = createRedirectUrlPlugin({
    onRedirect,
  });

  autocomplete({
    container: "#autocomplete",
    openOnFocus: true,
    plugins: [redirectUrlPlugin],
    getSources({ query }) {
      return [
        {
          sourceId: "demo-source",
          templates: {
            item(params) {
              const { item, html } = params;
              return html`<a class="aa-ItemLink">${item.name}</a>`;
            },
          },
          getItemInputValue({ item }) {
            return item.name;
          },
          getItems() {
            return {}; // your custom results here...
          },
        },
      ];
    },
  });
  ```

  ```jsx JSX theme={"system"}
  import { autocomplete } from "@algolia/autocomplete-js";
  import { createRedirectUrlPlugin } from "@algolia/autocomplete-plugin-redirect-url";

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

  function onRedirect(redirects, { event, navigator, state }) {
    const item = redirects.find(
      (r) => r.sourceId === "my-source-with-two-queries",
    );
    const itemUrl = item?.urls?.find((url) =>
      url.startsWith("https://www.algolia.com"),
    );

    if (!itemUrl) {
      return;
    }

    if (event.metaKey || event.ctrlKey) {
      navigator.navigateNewTab({ itemUrl, item, state });
    } else if (event.shiftKey) {
      navigator.navigateNewWindow({ itemUrl, item, state });
    } else {
      navigator.navigate({ itemUrl, item, state });
    }
  }

  const redirectUrlPlugin = createRedirectUrlPlugin({
    onRedirect,
  });

  autocomplete({
    container: "#autocomplete",
    openOnFocus: true,
    plugins: [redirectUrlPlugin],
    getSources({ query }) {
      return [
        {
          sourceId: "demo-source",
          templates: {
            item(params) {
              const { item } = params;
              return <a class="aa-ItemLink">${item.name}</a>;
            },
          },
          getItemInputValue({ item }) {
            return item.name;
          },
          getItems() {
            return {}; // your custom results here...
          },
        },
      ];
    },
  });
  ```
</CodeGroup>

## Customize rendering of redirect items

You can use the [`templates`](/doc/ui-libraries/autocomplete/api-reference/autocomplete-plugin-redirect-url/createRedirectUrlPlugin#param-templates)
parameter to change the default rendering of redirect items:

<CodeGroup>
  ```js JavaScript theme={"system"}
  import { autocomplete } from "@algolia/autocomplete-js";
  import { createRedirectUrlPlugin } from "@algolia/autocomplete-plugin-redirect-url";

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

  const templates = {
    item({ html, state }) {
      return html`<a className="myCustomClass">${state.query}</a>`;
    },
  };

  const redirectUrlPlugin = createRedirectUrlPlugin({
    templates,
  });

  autocomplete({
    container: "#autocomplete",
    placeholder: "Search",
    openOnFocus: true,
    plugins: [redirectUrlPlugin],
    getSources({ query }) {
      return [
        {
          sourceId: "demo-source",
          templates: {
            item(params) {
              const { item, html } = params;
              return html`<a class="aa-ItemLink">${item.name}</a>`;
            },
          },
          getItemInputValue({ item }) {
            return item.name;
          },
          getItems() {
            return {}; // your custom results here...
          },
        },
      ];
    },
  });
  ```

  ```jsx JSX theme={"system"}
  import { autocomplete } from "@algolia/autocomplete-js";
  import { createRedirectUrlPlugin } from "@algolia/autocomplete-plugin-redirect-url";

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

  const templates = {
    item({ state }) {
      return <a className="myCustomClass">${state.query}</a>;
    },
  };

  const redirectUrlPlugin = createRedirectUrlPlugin({
    templates,
  });

  autocomplete({
    container: "#autocomplete",
    placeholder: "Search",
    openOnFocus: true,
    plugins: [redirectUrlPlugin],
    getSources({ query }) {
      return [
        {
          sourceId: "demo-source",
          templates: {
            item(params) {
              const { item } = params;
              return <a class="aa-ItemLink">${item.name}</a>;
            },
          },
          getItemInputValue({ item }) {
            return item.name;
          },
          getItems() {
            return {}; // your custom results here...
          },
        },
      ];
    },
  });
  ```
</CodeGroup>
