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

# Keep track of query IDs

> Pass query IDs as URL parameter to product detail pages to track conversion events related to search.

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 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 Events = () => <Tooltip tip="An event is a specific action a user takes in your app or on your website." cta="Events" href="/doc/guides/sending-events">
    events
  </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>;

Often, conversions start with a <SearchQuery /> and finish outside the search results page.
For example, consider this sequence of user <Events /> on an ecommerce website:

1. User searches for a product or browses a category page.
2. User clicks on one or more products and opens their product detail pages.
3. After visiting one or more product detail pages, the user adds the product they like the most to the shopping cart.

To track conversion events related to an Algolia search query,
capture and send the search `queryID` with the event.

To keep track of `queryID`s across pages, include them as URL parameters.

To track conversions unrelated to a previous search,
you can [send a conversion event without a `queryID`](/doc/libraries/sdk/v1/methods/converted-object-ids).

<Info>
  Events without a query ID are not considered for most Algolia features.
  For more information about the types of events accepted by each feature,
  refer to the [**Events by features**](/doc/guides/sending-events/concepts/event-types#events-by-features) table.
</Info>

If you're using the Google Tag Manager connector, see [its documentation](/doc/guides/sending-events/connectors/google-tag-manager).

## Automatic query ID inference for conversion events

Algolia automatically infers the `queryID` for a conversion event from an earlier click event if the events share the same [user token](/doc/guides/sending-events/concepts/usertoken), <Application />, <Index />, and `objectID`.
This happens when Algolia processes events:
no additional configuration is required.

This means manual `queryID` tracking may not be necessary.
However, for best accuracy, set the `queryID` whenever possible.

## Get the `queryID` for every search

To generate a `queryID` with every search,
set the [`clickAnalytics`](/doc/api-reference/api-parameters/clickAnalytics) parameter to `true`.

If you're using one of the API clients, run:

<CodeGroup>
  ```cs C# theme={"system"}
  var response = await client.SearchSingleIndexAsync<Hit>(
    "INDEX_NAME",
    new SearchParams(new SearchParamsObject { ClickAnalytics = true })
  );
  ```

  ```dart Dart theme={"system"}
  final response = await client.searchSingleIndex(
    indexName: "INDEX_NAME",
    searchParams: SearchParamsObject(
      clickAnalytics: true,
    ),
  );
  ```

  ```go Go theme={"system"}
  response, err := client.SearchSingleIndex(client.NewApiSearchSingleIndexRequest(
    "INDEX_NAME").WithSearchParams(search.SearchParamsObjectAsSearchParams(
    search.NewEmptySearchParamsObject().SetClickAnalytics(true))))
  if err != nil {
    // handle the eventual error
    panic(err)
  }
  ```

  ```java Java theme={"system"}
  SearchResponse response = client.searchSingleIndex("INDEX_NAME", new SearchParamsObject().setClickAnalytics(true), Hit.class);
  ```

  ```js JavaScript theme={"system"}
  const response = await client.searchSingleIndex({ indexName: 'indexName', searchParams: { clickAnalytics: true } });
  ```

  ```kotlin Kotlin theme={"system"}
  var response =
    client.searchSingleIndex(
      indexName = "INDEX_NAME",
      searchParams = SearchParamsObject(clickAnalytics = true),
    )
  ```

  ```php PHP theme={"system"}
  $response = $client->searchSingleIndex(
      'INDEX_NAME',
      ['clickAnalytics' => true,
      ],
  );
  ```

  ```python Python theme={"system"}
  response = client.search_single_index(
      index_name="INDEX_NAME",
      search_params={
          "clickAnalytics": True,
      },
  )
  ```

  ```ruby Ruby theme={"system"}
  response = client.search_single_index(
    "INDEX_NAME",
    Algolia::Search::SearchParamsObject.new(click_analytics: true)
  )
  ```

  ```scala Scala theme={"system"}
  val response = Await.result(
    client.searchSingleIndex(
      indexName = "INDEX_NAME",
      searchParams = Some(
        SearchParamsObject(
          clickAnalytics = Some(true)
        )
      )
    ),
    Duration(100, "sec")
  )
  ```

  ```swift Swift theme={"system"}
  let response: SearchResponse<Hit> = try await client.searchSingleIndex(
      indexName: "INDEX_NAME",
      searchParams: SearchSearchParams.searchSearchParamsObject(SearchSearchParamsObject(clickAnalytics: true))
  )
  ```
</CodeGroup>

If you're using InstantSearch or Autocomplete,
set the `insights` option to `true`:

* [Autocomplete](/doc/ui-libraries/autocomplete/guides/sending-algolia-insights-events#enable-the-insights-option)
* [InstantSearch](/doc/guides/sending-events/instantsearch/send-events#enable-events-collection)

## Use InstantSearch or Autocomplete to track the `queryID` for conversion events

InstantSearch and Autocomplete keep track of the `queryID` when users click search results.
When sending conversion events, [`search-insights`](/doc/libraries/search-insights) automatically includes the `queryID` in the event payload if you
[pass `inferQueryID: true` for each call](/doc/libraries/sdk/v1/methods/send-events#param-additional-params).

## Track the `queryID` as a URL parameter

You can add the `queryID` as a URL parameter to the URL of the product detail page.
For example, on your InstantSearch search results page:

<CodeGroup>
  ```js JavaScript theme={"system"}
  search.addWidgets([
    instantsearch.widgets.hits({
      templates: {
        item: (item, { html }) =>
          html`...`
      }
    })
  ]);
  ```

  ```jsx React theme={"system"}
  const Hit = ({ hit }) => (
    <article>
      <a href={`/product.html?queryID=${hit.__queryID}`}>
        {/* ... */}
      </a>
    </article>
  );
  ```

  ```vue Vue theme={"system"}
  <ais-hits>
    <template v-slot:item="{ item }">
      <a href="/product.html?queryID={{item.__queryID}}">
        ...
      </a>
    </template>
  </ais-hits>
  ```
</CodeGroup>

To read the `queryID` from the URL, you can use the [URL API](https://developer.mozilla.org/en-US/docs/Web/API/URL/searchParams):

```js JavaScript icon=code theme={"system"}
const url = new URL(window.location.href)
const searchParams = url.searchParams

const queryID = searchParams.get('queryID')
```

Tracking the `queryID` with URL parameters is the best way to ensure that conversion events match the correct search.
For example, users might open several product detail pages from your category page or search results.
This pattern is sometimes called [page parking](https://www.nngroup.com/articles/multi-tab-page-parking/).

When you use URL parameters to keep track of the query ID,
follow [SEO best practices](/doc/guides/building-search-ui/resources/seo/js).
For more advice, read the article [URL parameter handling](https://www.searchenginejournal.com/technical-seo/url-parameter-handling/) in the Search Engine Journal.

## Track the `queryID` in cookies or local storage

You could track the `queryID` in a `cookie`, `localStorage`, or `sessionStorage`.

For example, to store the latest `queryID` in the browser's local storage:

```js JavaScript icon=code theme={"system"}
// Write `queryID` to local storage
localStorage.setItem("queryID", queryID);

// Read `queryID` from local storage
let queryID = localStorage.getItem("queryID");
```

This example only stores one `queryID` from the last search query that the user performed.
If the user has several product detail pages open from previous searches,
the conversion event won't have the correct `queryID`.

Storing the `queryID` in a cookie or the browser's local storage may require your users' consent.

## Send the conversion event

To send the conversion event, use the [`convertedObjectIDsAfterSearch`](/doc/libraries/sdk/v1/methods/converted-object-ids-after-search) method.

If no `queryID` is provided, Algolia will attempt to infer it based on an earlier click event that shares the same `objectID`, app, index, and [user token](/doc/guides/sending-events/concepts/usertoken).
This ensures more accurate tracking of conversions even when explicit `queryID` tracking is unavailable.
