Implement tabs

This is for:

Developer
In this article

A search interface 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 expression on queries. However, it may also have other effects, such as routing queries through a specific query pipeline, modifying the maximum age of cached query result sets, or toggling the visibility of certain elements in the search interface. This article provides guidelines for implementing tabs on your own, assuming that you can’t use the Coveo JavaScript Search Framework or the Atomic or Headless libraries in your custom search integration with the Coveo Platform.

Note

As a reference, you may want to look at the source code of the Tab component to see how it’s implemented in the Coveo JavaScript Search Framework.

Select a tab

When the user selects a tab, such as by clicking the corresponding link or button:

  1. Prepare a new query. Ensure that:

    • The tab search request parameter is set to the name or identifier of the newly selected tab (for example, BooksTab).

    • The cq search request parameter includes the static filter expression enforced by the newly selected tab, if any, and no longer contains the expression enforced by the previously selected tab, 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 performance.

    • Other search request parameters are set as required to further customize the behavior of the tab, such as enableDuplicateFiltering, maximumAge, pipeline, or sortCriteria.

      Note

      Duplicate filtering and result folding are mutually exclusive.

  2. Call the Search API to execute the query prepared in step 1. When the Search API returns:

    1. Call the usage analytics (UA) Write API to log the corresponding search event. In the request body:

      • Set the actionCause property to interfaceChange.

      • Include the following key-value pair in the customData property:

        • "interfaceChangeTo": <interfaceChangeTo>

        where:

        • <interfaceChangeTo> (string) is the name or identifier of the newly selected tab (for example, BooksTab).

      • Set the originLevel2 property to the same value as the tab search request parameter (that is, the name or identifier of the newly selected tab).

      • Set other required or optional properties as needed, such as queryText, language, or originLevel1.

    2. Render the query results.

    3. Render the facets, if any.

    4. Hide or show elements in the search interface as required by the newly selected tab, if applicable.

Note

These guidelines suggest a rather simplistic tab implementation. In a search interface that relies on the Coveo JavaScript Search Framework, selecting a Tab component instance may also have the following effects:

  • Route subsequent queries 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.

Moreover, selecting a Coveo JavaScript Search Framework Tab component instance can optionally contribute a static filter expression to the advanced query expression (aq) rather than to the constant query expression (cq).

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, and logs a search event as described in step 2.a.

Examples of selecting a tab

  1. Executing a query after the Books tab has been selected:

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

    Payload (excerpt)

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

    200 OK response body (excerpt)

    {
      ...
      "duration": 145,
      "groupByResults": [
        ...
      ],
      "results": [
        ...
      ],
      "searchUid": "7bfc652a-9dea-4811-b3f9-6d24345c37ce"
    }
  2. Logging a search event for the previous action:

    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)

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