---
title: Implement tabs
slug: '1382'
canonical_url: https://docs.coveo.com/en/1382/
collection: build-a-search-ui
source_format: adoc
---
# Implement tabs

A [search interface](https://docs.coveo.com/en/2741.md) often includes a single-select widget that the user can interact with to address different search needs.
Selecting an item in this widget typically enforces a static [filter](https://docs.coveo.com/en/2736.md) expression on [queries](https://docs.coveo.com/en/231.md).
However, it may also have other effects, such as routing [queries](https://docs.coveo.com/en/231.md) through a specific [query pipeline](https://docs.coveo.com/en/180.md), modifying the maximum age of cached [query](https://docs.coveo.com/en/231.md) result sets, or toggling the visibility of certain elements in the [search interface](https://docs.coveo.com/en/2741.md).
This article provides guidelines for implementing [tabs](https://docs.coveo.com/en/1406.md) on your own, assuming that you can't use the [Coveo JavaScript Search Framework](https://docs.coveo.com/en/187.md) or the [Atomic](https://docs.coveo.com/en/lcdf0264.md) or [Headless](https://docs.coveo.com/en/lcdf0493.md) libraries in your custom search integration with the [Coveo Platform](https://docs.coveo.com/en/186.md).

> **Note**
>
> As a reference, you may want to look at the source code of the [`Tab`](https://coveo.github.io/search-ui/components/tab.html) component to see how it's implemented in the [Coveo JavaScript Search Framework](https://docs.coveo.com/en/187.md).

## Select a tab

When the user selects a [tab](https://docs.coveo.com/en/1406.md), such as by clicking the corresponding link or button:

1. Prepare a new [query](https://docs.coveo.com/en/231.md).
Ensure that:

  * The [`tab`](https://docs.coveo.com/en/13.md#operation/searchUsingPost-tab) search request parameter is set to the name or identifier of the newly selected [tab](https://docs.coveo.com/en/1406.md) (for example, `BooksTab`).

  * The [`cq`](https://docs.coveo.com/en/13.md#operation/searchUsingPost-cq) search request parameter includes the static [filter](https://docs.coveo.com/en/2736.md) expression enforced by the newly selected [tab](https://docs.coveo.com/en/1406.md), if any, and no longer contains the expression enforced by the previously selected [tab](https://docs.coveo.com/en/1406.md), if applicable.

    > **Important**
    >
    > Avoid including user input or dynamic content in the `cq` search request parameter.
    > Otherwise, you risk filling the cache with useless data, which may adversely impact [query](https://docs.coveo.com/en/231.md) performance.

  * Other search request parameters are set as required to further customize the behavior of the [tab](https://docs.coveo.com/en/1406.md), such as [`enableDuplicateFiltering`](https://docs.coveo.com/en/13.md#operation/searchUsingPost-enableDuplicateFiltering), [`maximumAge`](https://docs.coveo.com/en/13.md#operation/searchUsingPost-maximumAge), [`pipeline`](https://docs.coveo.com/en/13.md#operation/searchUsingPost-pipeline), or [`sortCriteria`](https://docs.coveo.com/en/13.md#operation/searchUsingPost-sortCriteria).

    > **Note**
    >
    > Duplicate filtering and [result folding](https://docs.coveo.com/en/1466.md) are mutually exclusive.

1. Call the Search API to [execute the query](https://docs.coveo.com/en/1445.md) prepared in step 1.
When the Search API returns:

   1. Call the Usage Analytics Write API to [log the corresponding search event](https://docs.coveo.com/en/1502.md).
In the request body:

    * Set the [`actionCause`](https://docs.coveo.com/en/1502.md#actioncause-string) property to `interfaceChange`.

    * Include the following key-value pair in the [`customData`](https://docs.coveo.com/en/1502.md#search-event-customdata-key-value-pairs) property:

      --
      * `"interfaceChangeTo": <interfaceChangeTo>`
--
+
where:
+
--
      * `<interfaceChangeTo>` (string) is the name or identifier of the newly selected [tab](https://docs.coveo.com/en/1406.md) (for example, `BooksTab`).
--

    * Set the [`originLevel2`](https://docs.coveo.com/en/1502.md#originlevel2-string) property to the same value as the `tab` search request parameter (that is, the name or identifier of the newly selected [tab](https://docs.coveo.com/en/1406.md)).

    * Set other required or optional properties as needed, such as [`queryText`](https://docs.coveo.com/en/1502.md#querytext-string), [`language`](https://docs.coveo.com/en/1502.md#language-string), or [`originLevel1`](https://docs.coveo.com/en/1502.md#originlevel1-string).

   1. [Render the query results](https://docs.coveo.com/en/1372.md#render-query-results).

   1. [Render the facets](https://docs.coveo.com/en/3199.md#request-and-render-facets), if any.

   1. Hide or show elements in the [search interface](https://docs.coveo.com/en/2741.md) as required by the newly selected [tab](https://docs.coveo.com/en/1406.md), if applicable.

> **Note**
>
> These guidelines suggest a rather simplistic [tab](https://docs.coveo.com/en/1406.md) implementation.
> In a [search interface](https://docs.coveo.com/en/2741.md) that relies on the [Coveo JavaScript Search Framework](https://docs.coveo.com/en/187.md), selecting a [`Tab`](https://coveo.github.io/search-ui/components/tab.html) component instance may also have the following effects:
>
> * Route subsequent [queries](https://docs.coveo.com/en/231.md) to a different search endpoint altogether (that is, possibly use a different access token or set of search request parameters).
>
> * [Change the default result list layout](https://docs.coveo.com/en/1372.md#switch-result-list-layouts).
>
> Moreover, selecting a [Coveo JavaScript Search Framework](https://docs.coveo.com/en/187.md) `Tab` component instance can optionally contribute a static [filter](https://docs.coveo.com/en/2736.md) expression to the [advanced query expression](https://docs.coveo.com/en/175.md) ([`aq`](https://docs.coveo.com/en/13.md#operation/searchUsingPost-aq)) rather than to the [constant query expression (`cq`)](https://docs.coveo.com/en/179.md).
>
> Regardless of its configuration, selecting a `Tab` component instance always sets the `tab` search request parameter to the name or identifier of the newly selected [tab](https://docs.coveo.com/en/1406.md), and logs a search event as described in step 2.a.

### Examples of selecting a tab

1. Executing a [query](https://docs.coveo.com/en/231.md) after the _Books_ [tab](https://docs.coveo.com/en/1406.md) has been selected:

   ```http
   POST https://myorganizationid9sd8df7s.org.coveo.com/rest/search/v2 HTTP/1.1
   ​
   Accept: application/json
   Content-Type: application/json
   Authorization: Bearer **********-****-****-****-************
   ```

   **Payload (excerpt)**

   ```json
   {
     ...
     "cq": "@documenttype==Book",
     "groupBy": [
       ...
     ],
     "locale": "en-US",
     "q": "John Keats",
     "searchHub": "BookstoreSearch",
     "tab": "Books",
     ...
   }
   ```

   **200 OK response body (excerpt)**

   ```json
   {
     ...
     "duration": 145,
     "groupByResults": [
       ...
     ],
     "results": [
       ...
     ],
     "searchUid": "7bfc652a-9dea-4811-b3f9-6d24345c37ce"
   }
   ```

1. Logging a search [event](https://docs.coveo.com/en/260.md) for the previous action:

   ```http
   POST https://myorganizationid9sd8df7s.analytics.org.coveo.com/rest/ua/v15/analytics/search?visitor=28s6g49d-f81s-1435-2r5x153dle72 HTTP/1.1
   ​
   Accept: application/json
   Content-Type: application/json
   Authorization: Bearer **********-****-****-****-************
   ```

   **Payload (excerpt)**

   ```json
   {
     ...
     "actionCause": "interfaceChange",
     "customData": {
       ...
       "interfaceChangeTo": "Books",
       ...
     },
     "language": "en",
     "originLevel1": "BookstoreSearch",
     "originLevel2": "Books",
     "queryText": "John Keats",
     "responseTime": 145,
     "searchQueryUid": "7bfc652a-9dea-4811-b3f9-6d24345c37ce",
     ...
   }
   ```