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

# ais-instant-search

> Root component for Vue InstantSearch apps.

export const SearchRequest = () => <Tooltip tip="A search request is a single HTTP call to the Algolia Search API that can run one or more search operations. It can include multiple queries, for example, when querying several indices at once.">
    search request
  </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 Facet = () => <Tooltip tip="An attribute in your records that lets users filter or group results (for example, by color, brand, or price)." cta="Faceting" href="/doc/guides/managing-results/refine-results/faceting">
    facet
  </Tooltip>;

```vue Signature theme={"system"}
<ais-instant-search
  index-name="string"
  :search-client="object"
  // Optional parameters
  :on-state-change="function"
  :search-function="function"
  :stalled-search-delay="number"
  :routing="object"
  :initial-ui-state="object"
  :class-names="object"
  :insights="boolean | object"
  :insights-client="function"
  :future="{
    preserveSharedStateOnUnmount: boolean,
    persistHierarchicalRootCount: boolean,
  }"
/>
```

## Import

You can import this widget in two ways.

<Tabs>
  <Tab title="Component">
    To ensure optimal bundle sizes,
    see [Optimize build size](/doc/guides/building-search-ui/going-further/improve-performance/vue#optimize-build-size).

    ```js Vue icon=code theme={"system"}
    import { AisInstantSearch } from "vue-instantsearch";
    // Use "vue-instantsearch/vue3/es" for Vue 3

    export default {
      components: {
        AisInstantSearch,
      },
      // ...
    };
    ```
  </Tab>

  <Tab title="Plugin">
    This imports all widgets, even the ones you don't use.
    For more information, see [Get started with Vue InstantSearch](/doc/guides/building-search-ui/getting-started/vue).

    ```js JavaScript icon="code" theme={"system"}
    import Vue from "vue";
    import InstantSearch from "vue-instantsearch";
    // Use "vue-instantsearch/vue3/es" for Vue 3

    Vue.use(InstantSearch);
    ```
  </Tab>
</Tabs>

<Card title="See this widget in action" icon="monitor-play" href="https://instantsearchjs.netlify.app/stories/vue/?selectedKind=ais-instant-search" horizontal>
  Preview this widget and its behavior.
</Card>

## About this widget

`ais-instant-search` is the root wrapper component for all widgets.

### Middleware

Vue InstantSearch provides middleware to help you connect to other systems:

* **Insights.**
  Use the [`insights`](/doc/api-reference/widgets/insights/vue) middleware to [send click and conversion events](/doc/guides/building-search-ui/events/vue).

* **Generic.**
  With the [`middleware`](/doc/api-reference/widgets/middleware/vue) API,
  you can inject logic into Vue InstantSearch.
  For example, to [send events to Google Analytics](/doc/guides/building-search-ui/going-further/integrate-google-analytics/vue).

## Examples

```vue Vue icon=code theme={"system"}
<template>
  <ais-instant-search
    index-name="INDEX_NAME"
    :search-client="searchClient"
  >
    <!-- Widgets -->
  </ais-instant-search>
</template>

<script>
import { liteClient as algoliasearch } from "algoliasearch/lite";

export default {
  data() {
    return {
      searchClient: algoliasearch("YourApplicationID", "YourSearchOnlyAPIKey"),
    };
  },
};
</script>
```

## Props

<ParamField body="index-name" type="string" required>
  The main <Index /> in which to search.

  ```vue Vue icon=code theme={"system"}
  <ais-instant-search
    [...]
    index-name="INDEX_NAME"
  >
    <!-- Widgets -->
  </ais-instant-search>
  ```
</ParamField>

<ParamField body="search-client" type="object" required>
  Provides a search client to `ais-instant-search`.
  Read [the custom backend guidance](/doc/guides/building-search-ui/going-further/backend-search/vue)
  on implementing a custom search client.

  The client uses a cache to avoid unnecessary search operations,
  so you should use a stable reference to the same search client instance rather than creating a new one on each render.
  Avoid inlining the function call to `algoliasearch` as the prop value in your Vue template.

  ```vue Vue icon=code theme={"system"}
  <template>
    <ais-instant-search
      [...]
      :search-client="searchClient"
    >
      <!-- Widgets -->
    </ais-instant-search>
  </template>

  <script>
  import { liteClient as algoliasearch } from "algoliasearch/lite";

  export default {
    data() {
      return {
        searchClient: algoliasearch("YourApplicationID", "YourSearchOnlyAPIKey"),
      };
    },
  };
  </script>
  ```
</ParamField>

<ParamField body="search-function" type="function">
  This option lets you take control of search behavior.
  For example, to avoid doing searches at page load.

  When this option is set, `search.helper` won't emit events.
  Instead, use [`onStateChange`](#param-on-state-change)
  or widgets to handle search behavior.

  A hook is called for every <SearchRequest />
  (with [Algolia's search helper](/doc/guides/building-search-ui/upgrade-guides/js#algolia-search-helper)
  as a parameter).
  Begin searching by calling [`helper.search()`](https://instantsearchjs.netlify.app/algoliasearch-helper-js/reference.html#AlgoliaSearchHelper#search).

  When modifying the state of the helper within `search-function`,
  the helper resets the page to 0.
  To keep the current page, store the page information,
  modify the state, and reapply pagination.

  <CodeGroup>
    ```vue Function theme={"system"}
    <template>
      <ais-instant-search
        [...]
        :search-function="searchFunction"
      >
        <!-- Widgets -->
      </ais-instant-search>
    </template>

    <script>
    export default {
      data() {
        return {
          // ...
          searchFunction(helper) {
            if (helper.state.query) {
              helper.search();
            }
          },
        };
      },
    };
    </script>
    ```

    ```vue Prevent page reset theme={"system"}
    <template>
      <ais-instant-search
        [...]
        :search-function="searchFunction"
      >
        <!-- Widgets -->
      </ais-instant-search>
    </template>

    <script>
    export default {
      data() {
        return {
          // ...
          searchFunction(helper) {
            const page = helper.getPage(); // Retrieve the current page

            helper
              .setQuery("Hello") // this call resets the page
              .setPage(page) // we re-apply the previous page
              .search();
          },
        };
      },
    };
    </script>
    ```
  </CodeGroup>
</ParamField>

<ParamField body="on-state-change" type="function">
  Triggers when the state changes.
  This can be useful when performing custom logic on a state change.

  When using `on-state-change`, the instance is under your control.
  **You're responsible for updating the UI state (with `setUiState`).**

  ```vue Vue icon=code theme={"system"}
  <template>
    <ais-instant-search
      [...]
      :on-state-change="onStateChange"
    >
      <!-- Widgets -->
    </ais-instant-search>
  </template>

  <script>
  export default {
    data() {
      return {
        // ...
        onStateChange({ uiState, setUiState }) {
          // Custom logic

          setUiState(uiState);
        },
      };
    },
  };
  </script>
  ```
</ParamField>

<ParamField body="stalled-search-delay" type="number" default={200}>
  A time period (in ms) after which the search is considered to have stalled.
  Read the [slow network guide](/doc/guides/building-search-ui/going-further/improve-performance/vue) for more information.

  ```vue Vue icon=code theme={"system"}
  <ais-instant-search
    [...]
    :stalled-search-delay="1000"
  >
    <!-- Widgets -->
  </ais-instant-search>
  ```
</ParamField>

<ParamField body="routing" type="boolean | object" default={false}>
  The router configuration used to save the UI state into the URL or any client-side persistence.

  <Expandable title="routing attributes">
    <ParamField body="routing.router" type="object">
      This object stores the UI state.
      By default, it uses an instance of the [`history`](/doc/api-reference/widgets/history-router/vue)
      router with its default parameters.

      <Expandable title="router attributes">
        <ParamField body="router.onUpdate" type="function">
          Adds an event listener that makes InstantSearch aware of external changes to the storage medium (such as the URL).
          Typically you'll set up a listener for `popstate`,
          which triggers a callback with the current `routeState`.
        </ParamField>

        <ParamField body="router.read" type="function">
          Reads the routing storage and gets `routeState` object.
          It doesn't take any parameters but returns an object.
        </ParamField>

        <ParamField body="router.write" type="function">
          Pushes `routeState` into routing storage.
        </ParamField>

        <ParamField body="router.createURL" type="function">
          Transforms `routeState` into a URL.
          It receives an object and returns a string (which may be empty).
        </ParamField>

        <ParamField body="router.dispose" type="function">
          Cleans up all event listeners.
        </ParamField>
      </Expandable>
    </ParamField>

    <ParamField body="routing.stateMapping" type="object">
      Transforms the [`uiState`](/doc/api-reference/widgets/ui-state/vue)
      into the object saved by the router.
      The default value is provided by [`simple`](/doc/api-reference/widgets/simple-state-mapping/vue).

      <Expandable title="stateMapping attributes">
        <ParamField body="stateMapping.stateToRoute" type="function">
          Transforms a `ui-state` representation into `routeState`.
          It receives an object that contains the UI state of all the widgets n the page.
          It can return any object that's readable by `routeToState`.
        </ParamField>

        <ParamField body="stateMapping.routeToState" type="function">
          Transforms `routeState` into a `ui-state` representation.
          It receives an object that contains the UI state stored by the router.
          It can return any object that's readable by `stateToRoute`.
        </ParamField>
      </Expandable>
    </ParamField>
  </Expandable>

  For more information, see [Sync your URLs](/doc/guides/building-search-ui/going-further/routing-urls/vue).

  You can't use [`initialUiState`](#param-initial-ui-state) with routing as the two options override each other.

  * Use `initialUiState` for simple and static use cases.
  * Use `routing` for anything complex or dynamic.

  ```vue Vue icon=code theme={"system"}
  <template>
    <ais-instant-search
      [...]
      :routing="routing"
    >
      <!-- Widgets -->
    </ais-instant-search>
  </template>

  <script>
  import { history } from "instantsearch.js/es/lib/routers";
  import { simple } from "instantsearch.js/es/lib/stateMappings";

  export default {
    data() {
      return {
        // ...
        routing: {
          router: history(),
          stateMapping: simple(),
        },
      };
    },
  };
  </script>
  ```
</ParamField>

<ParamField body="initial-ui-state" type="object">
  Adds a [`uiState`](/doc/api-reference/widgets/ui-state/vue) to your `ais-instant-search` instance,
  which provides an initial state to your widgets.

  Replace `YourIndexName` with the name of your Algolia index.

  ```vue Vue icon=code theme={"system"}
  <template>
    <ais-instant-search
      :initial-ui-state="initialUiState"
    ></ais-instant-search>
  </template>

  <script>
  export default {
    data() {
      return {
        // ...
        initialUiState: {
          YourIndexName: {
            query: "phone",
            page: 5,
          },
        },
      };
    },
  };
  </script>
  ```
</ParamField>

<ParamField body="class-names" type="object" default="{}">
  The [CSS classes you can override](/doc/guides/building-search-ui/widgets/customize-an-existing-widget/vue#style-your-widgets):

  * `ais-InstantSearch`: the root of the widget.

  ```vue Vue icon=code theme={"system"}
  <ais-instant-search
    [...]
    :class-names="{
      'ais-InstantSearch': 'MyCustomInstantSearch',
    }"
  >
    <!-- Widgets -->
  </ais-instant-search>
  ```
</ParamField>

<ParamField body="insights" type="boolean | object" default={false} post={["since: v4.9.0"]}>
  Enables the Insights middleware and loads the [`search-insights`](https://github.com/algolia/search-insights.js) library (if not already loaded).
  The Insights middleware sends view and click events automatically, and lets you set up your own [click and conversion events](/doc/guides/building-search-ui/events/vue).
  To use this option with an object, refer to the [Insights middleware options](/doc/api-reference/widgets/insights/vue#options).

  <CodeGroup>
    ```vue boolean theme={"system"}
    <ais-instant-search
      [...]
      :insights="true"
    >
      <!-- Widgets -->
    </ais-instant-search>
    ```

    ```vue object theme={"system"}
    <template>
      <ais-instant-search
        [...]
        :insights="insights"
      >
        <!-- Widgets -->
      </ais-instant-search>
    </template>

    <script>
    export default {
      data() {
        return {
          // ...
          insights: {
            insightsClient: window.aa,
            insightsInitParams: {
              useCookie: false,
              // …
            },
            // …
          },
        };
      },
    };
    </script>
    ```
  </CodeGroup>
</ParamField>

<ParamField body="insights-client" deprecated type="function">
  Use [`insights`](#param-insights) instead.

  This function is exposed by the `search-insights` library (usually `window.aa`)
  and is required if you want to [send click and conversion events](/doc/guides/building-search-ui/events/vue)
  with the [`insights`](/doc/api-reference/widgets/insights/vue) middleware.

  ```vue Vue icon=code theme={"system"}
  <template>
    <ais-instant-search
      [...]
      :insights-client="insightsClient"
    >
      <!-- Widgets -->
    </ais-instant-search>
  </template>

  <script>
  export default {
    data() {
      return {
        // ...
        insightsClient: window.aa,
      };
    },
  };
  </script>
  ```
</ParamField>

<ParamField body="future" type="object">
  Test new InstantSearch features without affecting others.

  <Expandable title="future attributes">
    <ParamField body="future.preserveSharedStateOnUnmount" type="boolean" default={false} post={["since: v4.11.0"]}>
      Changes the way `dispose` is used in InstantSearch lifecycle.

      If `false` (the default), each widget unmounting will also remove its state, even if multiple widgets read that UI state.

      If `true`, each widget unmounting will only remove its state if it's the last of its type.
      This allows you to dynamically add and remove widgets without losing their state.

      ```vue Vue icon=code theme={"system"}
      <template>
        <ais-instant-search
          [...]
          :future="{
            preserveSharedStateOnUnmount: true,
          }"
        >
          <!-- Widgets -->
        </ais-instant-search>
      </template>
      ```
    </ParamField>

    <ParamField body="future.persistHierarchicalRootCount" type="boolean" default={false} post={["since: v4.13.1"]}>
      Whether to display a constant <Facet /> value count at the root of a hierarchical menu with active refinements.

      * If `false` (default), the facet value count at the root level shows the facet value count of the refined (child) facet's parent.
      * If `true`, the facet value count at the root level shows the sum of the facet value counts of all its children, with or without refined children.

      ```vue Vue icon=code theme={"system"}
      <template>
        <ais-instant-search
          [...]
          :future="{
            persistHierarchicalRootCount: true,
          }"
        >
          <!-- Widgets -->
        </ais-instant-search>
      </template>
      ```
    </ParamField>
  </Expandable>
</ParamField>

## HTML output

```html HTML icon=code-xml theme={"system"}
<div class="ais-InstantSearch">
  <!-- Widgets -->
</div>
```
