> ## 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 redirect a query to a URL using Rules.

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>;

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 Filter = () => <Tooltip tip="A filter is a condition that limits which records Algolia returns. Filters often use one or more facet-value pairs, such as brand:Apple AND color:red. You can also filter by numeric values, dates, tags, booleans, or geographic constraints." cta="Filtering" href="/doc/guides/managing-results/refine-results/faceting">
    filter
  </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>;

export const AlgoliaSearch = () => <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 80 80" width="20" height="20" className="inline" fill="none" role="presentation" ariaLabel="Algolia Search">
    <circle cx="40" cy="32" r="28" fill="#5468FF"></circle>
    <rect x="30" y="22" width="20" height="20" rx="10" fill="#fff"></rect>
    <path d="M43 63.5 54.5 60l6 17h-12L43 63.5Z" fill="#36395A"></path>
  </svg>;

Search isn't only about retrieving results.
Sometimes, depending on what users search for,
you might want to redirect them to a specific page of your website or mobile app.

Redirecting searches to a URL helps users in these cases:

* **Improve user experience and navigation**.
  For example, searching for "help" or "return policy" redirects users to a support page.
* **Display category pages for related keywords** to guarantee a consistent user experience and boost SEO by driving more traffic to category pages. For example, searching for a category keyword, such as, "TV" redirects users directly to the corresponding category page.
* **Promotional campaigns**.
  For example, searching for a specific artist name or brand redirects users to a landing page created specifically to support a promotional operation.
* **Crisis management**.
  Provide relevant answers to queries related to sudden events.
  For example, if you detect that your users suddenly start searching for "masks",
  redirect them to a specific landing page.

Algolia lets you create redirects to specific URLs with the
[Autocomplete redirect plugin](/doc/ui-libraries/autocomplete/guides/redirect) or a [custom implementation](/doc/guides/building-search-ui/ui-and-ux-patterns/redirects/js)

## Algolia out-of-the-box redirect solution

The easiest way to redirect search queries to a URL is by adding a rule with the [Visual Editor](/doc/guides/managing-results/rules/merchandising-and-promoting).
The rule adds data to the search response, which you can [handle in your frontend](#handle-redirects-in-your-user-interface).

The examples on this page add a redirect for the keyword "help" to a support page.
You can discover potential redirects by looking at your [search analytics](/doc/guides/search-analytics/overview).
For example, users searching for "help" and not getting any results.

### Create a rule in the Visual Editor

1. Go to the [Algolia dashboard](https://dashboard.algolia.com/explorer/browse) and select your Algolia <Application />.
2. On the left sidebar, select <AlgoliaSearch /> **Search**.
3. Select your Algolia <Index /> and go to the [**Rules**](https://dashboard.algolia.com/rules) page.
4. Click **Create your first Rule** or **New rule** and select **Visual Editor**.
5. In the **It all starts here** section, click **Set query conditions**.
6. In the **Your query** input, enter `help` and click **Apply**.
7. In the **What do you want to do?** section, click **Redirect**.
8. Enter the URL for your redirect—for example, the URL of your support page and click **Apply**.
9. Confirm your changes by clicking **Review and Publish**.

### Create a rule with the API

To run the code examples on this page, [install the latest API client](/doc/libraries/sdk/install).

To add a rule with the API, use the [`saveRule`](/doc/libraries/sdk/v1/methods/save-rule) method.
When adding a rule, you need to define a condition and a consequence.
In the consequence, [add a search parameters](/doc/guides/managing-results/rules/rules-overview/how-to/add-default-search-parameters-with-rules) and configure [`renderingContent`](/doc/api-reference/api-parameters/renderingContent) using the following template:

```json JSON icon=braces theme={"system"}
{
  "renderingContent": {
    "redirect": {
      "url": "https://www.algolia.com/support"
    }
  }
}
```

### Handle redirects in your user interface

After adding the rule, you can trigger the redirect in your UI when the `renderingContent.redirect` property is present in the API response. You have two options:

* Using the [redirect plugin](/doc/ui-libraries/autocomplete/guides/redirect) for the Autocomplete UI library
* Implement [your own logic](/doc/guides/building-search-ui/ui-and-ux-patterns/redirects/js)

## Extend the out-of-the-box approach or create custom redirection

If you want to define your own redirection format,
or if you need to add additional attributes to the [default redirect rule format](#algolia-out-of-the-box-redirect-solution),
you can create a rule with the **Manual Editor** that returns custom data.

### Create a rule for returning custom data

You can set a rule that contains the [custom data](/doc/guides/managing-results/rules/rules-overview/in-depth/implementing-rules#return-user-data) you need to build your custom redirect.

This example redirects users to your support page whenever the <SearchQuery /> contains "help".

#### Create a rule in the Manual Editor

1. Go to the [**Rules**](https://dashboard.algolia.com/rules) page.
2. Click **Create your first Rule** or **New rule** and select **Manual Editor**.
3. In the **Condition(s)** section, keep the **Query** option selected, and enter `help` in the input.
4. In the **Consequence(s)** section, click **Add consequence** and select **Return Custom Data**.
5. In the **Custom JSON data** input, add the data you want to return when the query matches the rule's condition. For example if you want to create a complete custom redirection, enter the following JSON object: `{"redirect": "https://www.algolia.com/support"}`
6. Optional: add a description for the rule, that helps you and your team distinguish it from other rules.
7. Click **Save**.

#### Create a rule with the API

To add a rule with the API, use the [`saveRule`](/doc/libraries/sdk/v1/methods/save-rule) method.
When setting a rule, you need to define a condition and a consequence.

<CodeGroup>
  ```cs C# theme={"system"}
  var response = await client.SaveRuleAsync(
    "INDEX_NAME",
    "redirect-help-rule",
    new Rule
    {
      ObjectID = "redirect-help-rule",
      Conditions = new List<Condition>
      {
        new Condition { Pattern = "help", Anchoring = Enum.Parse<Anchoring>("Contains") },
      },
      Consequence = new Consequence
      {
        UserData = new Dictionary<string, string>
        {
          { "redirect", "https://www.algolia.com/support" },
        },
      },
    }
  );
  ```

  ```dart Dart theme={"system"}
  final response = await client.saveRule(
    indexName: "INDEX_NAME",
    objectID: "redirect-help-rule",
    rule: Rule(
      objectID: "redirect-help-rule",
      conditions: [
        Condition(
          pattern: "help",
          anchoring: Anchoring.fromJson("contains"),
        ),
      ],
      consequence: Consequence(
        userData: {
          'redirect': "https://www.algolia.com/support",
        },
      ),
    ),
  );
  ```

  ```go Go theme={"system"}
  response, err := client.SaveRule(client.NewApiSaveRuleRequest(
    "INDEX_NAME", "redirect-help-rule",
    search.NewEmptyRule().SetObjectID("redirect-help-rule").SetConditions(
      []search.Condition{*search.NewEmptyCondition().SetPattern("help").SetAnchoring(search.Anchoring("contains"))}).SetConsequence(
      search.NewEmptyConsequence().SetUserData(map[string]any{"redirect": "https://www.algolia.com/support"}))))
  if err != nil {
    // handle the eventual error
    panic(err)
  }
  ```

  ```java Java theme={"system"}
  UpdatedAtResponse response = client.saveRule(
    "INDEX_NAME",
    "redirect-help-rule",
    new Rule()
      .setObjectID("redirect-help-rule")
      .setConditions(Arrays.asList(new Condition().setPattern("help").setAnchoring(Anchoring.CONTAINS)))
      .setConsequence(
        new Consequence().setUserData(
          new HashMap() {
            {
              put("redirect", "https://www.algolia.com/support");
            }
          }
        )
      )
  );
  ```

  ```js JavaScript theme={"system"}
  const response = await client.saveRule({
    indexName: 'indexName',
    objectID: 'redirect-help-rule',
    rule: {
      objectID: 'redirect-help-rule',
      conditions: [{ pattern: 'help', anchoring: 'contains' }],
      consequence: { userData: { redirect: 'https://www.algolia.com/support' } },
    },
  });
  ```

  ```kotlin Kotlin theme={"system"}
  var response =
    client.saveRule(
      indexName = "INDEX_NAME",
      objectID = "redirect-help-rule",
      rule =
        Rule(
          objectID = "redirect-help-rule",
          conditions =
            listOf(
              Condition(
                pattern = "help",
                anchoring = Anchoring.entries.first { it.value == "contains" },
              )
            ),
          consequence =
            Consequence(
              userData =
                buildJsonObject {
                  put("redirect", JsonPrimitive("https://www.algolia.com/support"))
                }
            ),
        ),
    )
  ```

  ```php PHP theme={"system"}
  $response = $client->saveRule(
      'INDEX_NAME',
      'redirect-help-rule',
      ['objectID' => 'redirect-help-rule',
          'conditions' => [
              ['pattern' => 'help',
                  'anchoring' => 'contains',
              ],
          ],
          'consequence' => ['userData' => ['redirect' => 'https://www.algolia.com/support',
          ],
          ],
      ],
  );
  ```

  ```python Python theme={"system"}
  response = client.save_rule(
      index_name="INDEX_NAME",
      object_id="redirect-help-rule",
      rule={
          "objectID": "redirect-help-rule",
          "conditions": [
              {
                  "pattern": "help",
                  "anchoring": "contains",
              },
          ],
          "consequence": {
              "userData": {
                  "redirect": "https://www.algolia.com/support",
              },
          },
      },
  )
  ```

  ```ruby Ruby theme={"system"}
  response = client.save_rule(
    "INDEX_NAME",
    "redirect-help-rule",
    Algolia::Search::Rule.new(
      algolia_object_id: "redirect-help-rule",
      conditions: [Algolia::Search::Condition.new(pattern: "help", anchoring: "contains")],
      consequence: Algolia::Search::Consequence.new(user_data: {redirect: "https://www.algolia.com/support"})
    )
  )
  ```

  ```scala Scala theme={"system"}
  val response = Await.result(
    client.saveRule(
      indexName = "INDEX_NAME",
      objectID = "redirect-help-rule",
      rule = Rule(
        objectID = "redirect-help-rule",
        conditions = Some(
          Seq(
            Condition(
              pattern = Some("help"),
              anchoring = Some(Anchoring.withName("contains"))
            )
          )
        ),
        consequence = Consequence(
          userData = Some(JObject(List(JField("redirect", JString("https://www.algolia.com/support")))))
        )
      )
    ),
    Duration(100, "sec")
  )
  ```

  ```swift Swift theme={"system"}
  let response = try await client.saveRule(
      indexName: "INDEX_NAME",
      objectID: "redirect-help-rule",
      rule: Rule(
          objectID: "redirect-help-rule",
          conditions: [SearchCondition(pattern: "help", anchoring: SearchAnchoring.contains)],
          consequence: SearchConsequence(userData: ["redirect": "https://www.algolia.com/support"])
      )
  )
  ```
</CodeGroup>

#### Handle redirects in your user interface

After adding the rule, you can trigger the redirect in your UI when the `userData` property is present in the API response.
If you're using one of the InstantSearch UI libraries, see [Redirects in InstantSearch](/doc/guides/building-search-ui/ui-and-ux-patterns/redirects/js).

## Add redirects using a dedicated index

You can set up redirects by creating a separate index with the list of redirects **and** the queries that trigger them. Whenever a user performs a search, you have to look in two indices: the regular index to search for items, and the redirect index that determines whether users should be redirected.

This technique is useful if you can't use rules,
or if you want to use other Algolia Search features with your redirect queries,
such as typo tolerance, synonyms, or a <Filter />.

### Dataset

```json JSON icon=braces theme={"system"}
[
  {
    "url": "https://www.google.com/#q=star+wars",
    "query_terms": ["star wars"]
  },
  {
    "url": "https://www.google.com/#q=star+wars+actors",
    "query_terms": ["george lucas", "luke skywalker"]
  }
]
```

Each record in this dataset has a `url` to redirect the queries, and a list of `query_terms`, that trigger the redirect.

For example, the query "star wars" should redirect to `https://www.google.com/#q=star+wars`.

* [Download the dataset](https://raw.githubusercontent.com/algolia/datasets/master/small/redirects.json)
* To learn how to import the dataset, see [Import from the dashboard](/doc/guides/sending-and-managing-data/send-and-update-your-data/how-to/importing-from-the-dashboard)

### Configure the redirect index

To trigger the redirect only if the query exactly matches one of the query terms,
add `query_terms` to the list of [`attributesForFaceting`](/doc/api-reference/api-parameters/attributesForFaceting),
so that you can filter on it:

<CodeGroup>
  ```js JavaScript theme={"system"}
  const algoliaClient = algoliasearch("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY");

  const customSearchClient = {
    ...algoliaClient,
    async search(requests) {
      if (requests[0].params.query) {
        const { results } = await algoliaClient.search([
          ...requests,
          {
            indexName: "your_redirect_index_name",
            params: {
              hitsPerPage: 1,
              facetFilters: [`query_terms:${requests[0].params.query}`],
            },
          },
        ]);

        const redirect = results.pop();

        if (redirect.hits.length) {
          window.location.href = redirect.hits[0].url;
        }

        return { results };
      } else {
        return algoliaClient.search(requests);
      }
    },
  };

  const search = instantsearch({
    indexName: "instant_search",
    searchClient: customSearchClient,
  });
  ```

  ```jsx React theme={"system"}
  const algoliaClient = algoliasearch("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY");

  const customSearchClient = {
    ...algoliaClient,
    async search(requests) {
      if (requests[0].params.query) {
        const { results } = await algoliaClient.search([
          ...requests,
          {
            indexName: "your_redirect_index_name",
            params: {
              hitsPerPage: 1,
              facetFilters: [`query_terms:${requests[0].params.query}`],
            },
          },
        ]);

        const redirect = results.pop();

        if (redirect.hits.length) {
          window.location.href = redirect.hits[0].url;
        }

        return { results };
      } else {
        return algoliaClient.search(requests);
      }
    },
  };

  const App = () => ({
    /* Widgets */
  });
  ```

  ```vue Vue theme={"system"}
  <template>
    <ais-instant-search
      index-name="instant_search"
      :search-client="customSearchClient"
    >
      <!-- Widgets -->
    </ais-instant-search>
  </template>

  <script>
    import algoliasearch from 'algoliasearch/lite';

    const algoliaClient = algoliasearch(
      'ALGOLIA_APPLICATION_ID',
      'ALGOLIA_API_KEY'
    );

    const customSearchClient = {
      ...algoliaClient,
      async search(requests) {
        if (requests[0].params.query) {
          const { results } = await algoliaClient.search([
            ...requests,
            {
              indexName: 'your_redirect_index_name',
              params: {
                hitsPerPage: 1,
                facetFilters: [`query_terms:${requests[0].params.query}`],
              },
            },
          ]);

          const redirect = results.pop();

          if (redirect.hits.length) {
            window.location.href = redirect.hits[0].url;
          }

          return { results };
        } else {
          return algoliaClient.search(requests);
        }
      },
    };

    export default {
      data() {
        return {
          customSearchClient,
        };
      },
    };
  </script>
  ```
</CodeGroup>

### Create a custom search client

You need to create a [custom search client](/doc/guides/building-search-ui/going-further/backend-search/js) that **simultaneously sends requests to the regular and redirect indices**.

The request to the redirect index is sent with:

* An empty query, so it doesn't filter with it
* A filter on `query_terms` with the content of the current query, to match only <Records /> that contain the current query exactly
* `hitsPerPage=1`, as you only need the first record

Whenever a record matches in the redirect index, a redirect is triggered:

<CodeGroup>
  ```cs C# theme={"system"}
  var response = await client.SetSettingsAsync(
    "INDEX_NAME",
    new IndexSettings { AttributesForFaceting = new List<string> { "query_terms" } }
  );
  ```

  ```dart Dart theme={"system"}
  final response = await client.setSettings(
    indexName: "INDEX_NAME",
    indexSettings: IndexSettings(
      attributesForFaceting: [
        "query_terms",
      ],
    ),
  );
  ```

  ```go Go theme={"system"}
  response, err := client.SetSettings(client.NewApiSetSettingsRequest(
    "INDEX_NAME",
    search.NewEmptyIndexSettings().SetAttributesForFaceting(
      []string{"query_terms"})))
  if err != nil {
    // handle the eventual error
    panic(err)
  }
  ```

  ```java Java theme={"system"}
  UpdatedAtResponse response = client.setSettings(
    "INDEX_NAME",
    new IndexSettings().setAttributesForFaceting(Arrays.asList("query_terms"))
  );
  ```

  ```js JavaScript theme={"system"}
  const response = await client.setSettings({
    indexName: 'INDEX_NAME',
    indexSettings: { attributesForFaceting: ['query_terms'] },
  });
  ```

  ```kotlin Kotlin theme={"system"}
  var response =
    client.setSettings(
      indexName = "INDEX_NAME",
      indexSettings = IndexSettings(attributesForFaceting = listOf("query_terms")),
    )
  ```

  ```php PHP theme={"system"}
  $response = $client->setSettings(
      'INDEX_NAME',
      ['attributesForFaceting' => [
          'query_terms',
      ],
      ],
  );
  ```

  ```python Python theme={"system"}
  response = client.set_settings(
      index_name="INDEX_NAME",
      index_settings={
          "attributesForFaceting": [
              "query_terms",
          ],
      },
  )
  ```

  ```ruby Ruby theme={"system"}
  response = client.set_settings(
    "INDEX_NAME",
    Algolia::Search::IndexSettings.new(attributes_for_faceting: ["query_terms"])
  )
  ```

  ```scala Scala theme={"system"}
  val response = Await.result(
    client.setSettings(
      indexName = "INDEX_NAME",
      indexSettings = IndexSettings(
        attributesForFaceting = Some(Seq("query_terms"))
      )
    ),
    Duration(100, "sec")
  )
  ```

  ```swift Swift theme={"system"}
  let response = try await client.setSettings(
      indexName: "INDEX_NAME",
      indexSettings: IndexSettings(attributesForFaceting: ["query_terms"])
  )
  ```
</CodeGroup>
