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

# middleware

> Adds custom logic to your Vue InstantSearch apps.

```vue Signature theme={"system"}
<ais-instant-search
  index-name="instant_search"
  :search-client="searchClient"
  :middlewares="middlewares"
>
  <!-- Widgets -->
</ais-instant-search>
```

## About this widget

The `middleware` function returns an object with [`onStateChange`](#param-on-state-change),
[`subscribe`](#param-subscribe),
and [`unsubscribe`](#param-unsubscribe) functions.

The `middleware` function doesn't perform any actions itself but lets you inject logic into Vue InstantSearch,
for example, [sending events to Google Analytics](/doc/guides/building-search-ui/going-further/integrate-google-analytics/vue).
To [send Algolia click and conversion events](/doc/guides/building-search-ui/events/vue),
use the [`insights`](/doc/api-reference/widgets/insights/vue) middleware.

### Requirements

* [Vue InstantSearch](https://github.com/algolia/instantsearch/tree/master/packages/vue-instantsearch) v3.7.0 or later.

## Examples

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

<script>
function middleware({ instantSearchInstance }) {
  return {
    onStateChange({ uiState }) {
      // Do something with `uiState` every time the state changes.
    },
    subscribe() {
      // Do something when the InstantSearch instance starts.
    },
    unsubscribe() {
      // Do something when the InstantSearch instance is disposed of.
    },
  };
}

export default {
  data() {
    return {
      // ...
      middlewares: [middleware],
    };
  },
};
</script>
```

## Options

<ParamField body="instantSearchInstance" type="object" required>
  You have access to [the instance of `instantsearch`](/doc/api-reference/widgets/instantsearch/js)
  which lets you read values from the instance or call instance methods like `addWidgets`, `setUiState`, and `refresh`.

  ```js JavaScript icon=code theme={"system"}
  function middleware({ instantSearchInstance }) {
    return {
      onStateChange({ uiState }) {
        // ...
      },
      subscribe() {
        // ...
      },
      unsubscribe() {
        // ...
      },
    };
  }
  ```
</ParamField>

## Hooks

<ParamField body="onStateChange" type="({ uiState }) => void" required>
  This function is called with [`uiState`](/doc/api-reference/widgets/ui-state/js) whenever the state changes.

  ```js JavaScript icon=code theme={"system"}
  function middleware({ instantSearchInstance }) {
    return {
      // ...
      onStateChange({ uiState }) {
        const indexName = "<your-index-name>";
        const { query } = uiState[indexName];
        const title = document.querySelector("<your-selector>");
        title.innerText = query ? `Query: ${query}` : `No query`;
      },
    };
  }
  ```
</ParamField>

<ParamField body="subscribe" type="() => void" required>
  This function is called when the InstantSearch instance starts (when `search.start()` is called).
  This is where you can add event listeners, subscribe to an API, and run any side effects.

  ```js JavaScript icon=code theme={"system"}
  function middleware({ instantSearchInstance }) {
    let subscription;
    let listener;

    return {
      // ...
      subscribe() {
        subscription = someAPI.subscribe();

        listener = (event) => {
          // do something
        };
        document
          .querySelector("<your-selector>")
          .addEventListener("click", listener);
      },
    };
  }
  ```
</ParamField>

<ParamField body="unsubscribe" type="() => void" required>
  This function is called when the InstantSearch instance is disposed of.
  You can clean up anything you initiated in the `subscribe` function.

  ```js JavaScript icon=code theme={"system"}
  function middleware({ instantSearchInstance }) {
    let subscription;
    let listener;

    return {
      // ...
      unsubscribe() {
        subscription.unsubscribe();

        document
          .querySelector("<your-selector>")
          .removeEventListener("click", listener);
      },
    };
  }
  ```
</ParamField>
