--- title: Implement a result list slug: '1372' canonical_url: https://docs.coveo.com/en/1372/ collection: build-a-search-ui source_format: adoc --- # Implement a result list A [search interface](https://docs.coveo.com/en/2741/) almost always displays a list of results which the user can use to interact with [query](https://docs.coveo.com/en/231/) result [items](https://docs.coveo.com/en/210/). This article provides guidelines for implementing a _result list_ on your own, assuming that you can't use the Coveo [Atomic](https://docs.coveo.com/en/lcdf0264/) or [Headless](https://docs.coveo.com/en/lcdf0493/) libraries in your custom search integration with the [Coveo Platform](https://docs.coveo.com/en/186/). > **Note** > > As a reference, you may want to look at the source code of the [`ResultList`](https://coveo.github.io/search-ui/components/resultlist.html) component to see how it's implemented in the [Coveo JavaScript Search Framework](https://docs.coveo.com/en/187/). ## Standard result list actions The following table lists some actions that you may want to make available in a result list implementation. Each entry indicates the specific [Coveo Analytics event](https://docs.coveo.com/en/260/) category, `actionCause` or `eventValue`, `eventType`, and `[customData](https://docs.coveo.com/en/1341/)` that [must be logged](https://docs.coveo.com/en/1373/) when the action is performed, as well as a link to the corresponding implementation guidelines. [%header,cols="7"] |=== |Result list action |[events](https://docs.coveo.com/en/260/) |`actionCause` |`eventType` |`eventValue` |`[customData](https://docs.coveo.com/en/1341/)` |Implementation guidelines |Click a result |Click |`documentOpen` |N/A |N/A |`author`, `contentIdKey`, `contentIdValue`, `documentTitle`, `documentURL` |[Open query results](#open-query-results) |Click a recommendation |Click |`recommendationOpen` |N/A |N/A |`author`, `contentIdKey`, `contentIdValue`, `documentTitle`, `documentURL` |[Open query results](#open-query-results) |Preview a result |Click |`documentQuickview` |N/A |N/A |`author`, `contentIdKey`, `contentIdValue`, `documentTitle`, `documentURL` |[Preview a result](#preview-a-result) |Select a page of results |Custom |N/A |`getMoreResults` |`pagerNumber` |`pagerNumber` |[Page query results](#page-query-results) |Select the next page of results |Custom |N/A |`getMoreResults` |`pagerNumber` |`pagerNext` |[Page query results](#page-query-results) |Select the previous page of results |Custom |N/A |`getMoreResults` |`pagerNumber` |`pagerPrevious` |[Page query results](#page-query-results) |Scroll to get more results in infinite scroll mode |Custom |N/A |`getMoreResults` |`pagerNumber` |`pagerScrolling` |[Page query results](#page-query-results) |Resize the number of results per page |Custom |N/A |`getMoreResults` |`pagerResize` |`currentResultsPerPage` |[Page query results](#page-query-results) |Sort results |Search |`resultsSort` |N/A |N/A |`resultsSortBy` |[Sort query results](#sort-query-results) |Change the result layout |Custom |N/A |`resultsLayout` |`changeResultsLayout` |`resultsLayoutChangeTo` |[Switch result list layouts](#switch-result-list-layouts) |Export to Excel |Custom |N/A |`misc` |`exportToExcel` |N/A |[Export results](#export-results) |Toggle a [facet](https://docs.coveo.com/en/198/) from a result list [item](https://docs.coveo.com/en/210/) |Search |`documentField` |N/A |N/A |`facetField`, `facetId`, `facetValue` |[Toggle a facet value from a result list item](#toggle-a-facet-value-from-a-result-list-item) |=== > **Note** > > It's important to use the proper `eventType`, `actionCause` or `eventValue`, and `[customData](https://docs.coveo.com/en/1341/)` when logging a [Coveo Analytics event](https://docs.coveo.com/en/260/) for a specific type of action in a [search interface](https://docs.coveo.com/en/2741/). > Otherwise: > > * [Coveo Analytics reports](https://docs.coveo.com/en/266/) may become incoherent in the underlying [Coveo organization](https://docs.coveo.com/en/185/) (especially if that [organization](https://docs.coveo.com/en/185/) powers both [Coveo JavaScript Search Framework](https://docs.coveo.com/en/187/) and custom [search interfaces](https://docs.coveo.com/en/2741/)). > > * The [Coveo Machine Learning (Coveo ML)](https://docs.coveo.com/en/188/) service may not function properly. ## Render query results You typically want to update the result list whenever a search request to the Search API returns. The `results` array of a [query](https://docs.coveo.com/en/231/) response contains the list of [query](https://docs.coveo.com/en/231/) result [items](https://docs.coveo.com/en/210/) which you typically rely on to render or update the result list. By default, the `results` array is [sorted by relevance](#sort-query-results) (that is, by descending [index](https://docs.coveo.com/en/204/) ranking `score` value), but you can modify this behavior using the [`sortCriteria`](https://docs.coveo.com/en/13#operation/searchUsingPost-sortCriteria) search request parameter. > **Note** > > In a [search interface](https://docs.coveo.com/en/2741/) with many similar results, you may want use the [`enableDuplicateFiltering`](https://docs.coveo.com/en/13#operation/searchUsingPost-enableDuplicateFiltering) search request parameter. > Result [items](https://docs.coveo.com/en/210/) are considered duplicates when the proportion of their data that's identical exceeds a certain threshold. > When `enableDuplicateFiltering` is set to `true` and some [items](https://docs.coveo.com/en/210/) are duplicates, only one of those [items](https://docs.coveo.com/en/210/) will appear in the `results` array of the [query](https://docs.coveo.com/en/231/) response. > > Duplicate filtering and [result folding](#handle-folded-results) are mutually exclusive. The following properties are especially useful when rendering a [query](https://docs.coveo.com/en/231/) result [item](https://docs.coveo.com/en/210/): * Descriptions: ** `title`: The title of the [item](https://docs.coveo.com/en/210/). Use this to render the [item](https://docs.coveo.com/en/210/) in the result list. This property should be saved, as its value will be required when [logging a UA click event for the item](#open-query-results). ** `excerpt`: Text segments from the [item](https://docs.coveo.com/en/210/), generated using [query](https://docs.coveo.com/en/231/) [keywords](https://docs.coveo.com/en/2738/). You can set the maximum length (in number of characters, `200` by default) using the `excerptLength` parameter in the search request. ** `firstSentences`: The first sentences of the [item](https://docs.coveo.com/en/210/). This property won't be populated unless the `retrieveFirstSentences` parameter is set to `true` in the search request. You can set the maximum length (in number of characters, `200` by default) using the `excerptLength` parameter in the search request. ** `summary`: A description of the [item](https://docs.coveo.com/en/210/), generated independently of [query](https://docs.coveo.com/en/231/) [keywords](https://docs.coveo.com/en/2738/). You can set the maximum length (in number of characters, `0` by default) using the `summaryLength` parameter in the search request. ** `printableUri`: A human-readable version of the [item](https://docs.coveo.com/en/210/) URI to be displayed. * Highlights: All of the preceding properties have a `Highlights` counterpart which contains an array of `{length, offset}` elements. Each of these elements indicates a [keyword](https://docs.coveo.com/en/2738/) to highlight (for example, using bold or italic text) when rendering the corresponding value. ** `titleHighlights` ** `excerptHighlights` ** `firstSentencesHighlights` ** `summaryHighlights` ** `printableUriHighlights` * Link: ** `clickUri`: The hyperlinkable [item](https://docs.coveo.com/en/210/) URI. Use this to define the target when rendering a link to the corresponding [item](https://docs.coveo.com/en/210/) (for example, as the value of the `href` attribute in an HTML anchor element). * [fields](https://docs.coveo.com/en/200/): The `raw` property of a [query](https://docs.coveo.com/en/231/) result [item](https://docs.coveo.com/en/210/) contains key-value pairs, each corresponding to the name of a [field](https://docs.coveo.com/en/200/) along with its value for that specific [item](https://docs.coveo.com/en/210/). The following [fields](https://docs.coveo.com/en/200/) are particularly important, and they should be included as `[customData](https://docs.coveo.com/en/1341/)` (if available) when [logging UA click events for that item](#open-query-results): -- ** `author`: The author of the [item](https://docs.coveo.com/en/210/). ** `permanentid`: The unique identifier of the [item](https://docs.coveo.com/en/210/) in the [index](https://docs.coveo.com/en/204/). -- > **Notes** > > * By default, values in multi-value [fields](https://docs.coveo.com/en/200/) are separated by semicolon characters. > For example, an [item](https://docs.coveo.com/en/210/) that corresponds to the coauthored book _The Talisman_ may have the following key-value pair: `"authors":"Stephen King;Peter Straub"`. > > * When performing [queries](https://docs.coveo.com/en/231/), you can take advantage of the [`fieldsToInclude`](https://docs.coveo.com/en/13#operation/searchUsingPost-fieldsToInclude) or [`fieldsToExclude`](https://docs.coveo.com/en/13#operation/searchUsingPost-fieldsToExclude) search request parameters to only request the [fields](https://docs.coveo.com/en/200/) which are required by your [search interface](https://docs.coveo.com/en/2741/). > By default, all [fields](https://docs.coveo.com/en/200/) are requested, which is typically non-optimal. * Miscellaneous: ** `uri`: The URI of the [item](https://docs.coveo.com/en/210/). Although you won't typically use this to render the [item](https://docs.coveo.com/en/210/) in the result list, this property should be saved, as its value will be required when [logging a UA click event for the item](#open-query-results). ** `isRecommendation`: Whether the [query](https://docs.coveo.com/en/231/) result [item](https://docs.coveo.com/en/210/) was recommended by a [Coveo ML](https://docs.coveo.com/en/188/) [Automatic Relevance Tuning (ART)](https://docs.coveo.com/en/1013/) [model](https://docs.coveo.com/en/1012/). You may want to use this property to render [Coveo ML](https://docs.coveo.com/en/188/) recommendations in a distinctive fashion in the result list. > **Leading practice** > > For legacy reasons, several of the preceding properties are duplicated in PascalCase. > For example, each [item](https://docs.coveo.com/en/210/) in the results array has both the `clickUri` and `ClickUri` properties. > You should always use the camelCase version (for example, `clickUri`). ### Example of rendering query results Executing a search [query](https://docs.coveo.com/en/231/): ```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 { ... "excerptlength": 200, "q": "karamazov", "retrieveFirstSentences": true, ... } ``` **200 OK response body (excerpt)** ```json { ... "results": [ { ... "clickUri": "https://example.com/books/the-brothers-karamazov", "excerpt": "The Brothers Karamazov is a passionate philosophical novel set in 19th-century Russia ... one of the supreme achievements in world literature.", "excerptHighlights": [ { "length": 9, "offset": 13 } ], "firstSentences": "The Brothers Karamazov is a passionate philosophical novel set in 19th-century Russia, that enters deeply into the ethical debates of God, free will, and morality. It's a spiritual drama of moral ...", "firstSentencesHighlights": [ { "length": 9, "offset": 13 } ], "isRecommendation": true, "printableUri": "https://example.com/books/the-brothers-karamazov", "printableUriHighlights": [ { "length": 9, "offset": 39 } ], "raw": { ... "author": "Fyodor Dostoyevsky", "permanentid": "648a63d6a19545297692b4ae41a7d5e947c711be5f3c23dff69af3106960", ... }, "summary": null, "summaryHighlights": [], "title": "The Brothers Karamazov", "titleHighlights": [ { "length": 9, "offset": 13 } ], "uri": "https://example.com/books/the-brothers-karamazov", ... }, ...next results... ], ... } ``` ## Open query results When the user opens a [query](https://docs.coveo.com/en/231/) result in a result list, such as by clicking a link which targets the corresponding [item](https://docs.coveo.com/en/210/): . Call the Usage Analytics Write API to [log the corresponding click event](https://docs.coveo.com/en/2064/). In the request body: ** Set the `actionCause` property to: *** `documentOpen` if the result [item](https://docs.coveo.com/en/210/) was opened in a standard [search interface](https://docs.coveo.com/en/2741/). *** `recommendationOpen` if the result [item](https://docs.coveo.com/en/210/) was opened in a [Content Recommendation (CR)](https://docs.coveo.com/en/1016/) [search interface](https://docs.coveo.com/en/2741/). ** Include the following key-value pairs (if available) in the `[customData](https://docs.coveo.com/en/1341/)` property: -- *** `"author": ` *** `"documentTitle": ` *** `"documentUrl": ` *** `"contentIdKey": ` *** `"contentIdValue": ` -- where: -- *** `` (string) is the `raw.author` value of the clicked [query](https://docs.coveo.com/en/231/) result [item](https://docs.coveo.com/en/210/). This can be an empty string. *** `` (string) is the `title` value of the clicked [query](https://docs.coveo.com/en/231/) result [item](https://docs.coveo.com/en/210/). *** `` (string) is the `uri` value of the clicked [query](https://docs.coveo.com/en/231/) result [item](https://docs.coveo.com/en/210/). *** `` (string) is the name of a [field](https://docs.coveo.com/en/200/) which uniquely and permanently identifies the clicked [item](https://docs.coveo.com/en/210/). > **Leading practice** > > Use [`"permanentid"`](https://docs.coveo.com/en/1913/). > > If this is unavailable, such as if the clicked [item](https://docs.coveo.com/en/210/) resides in a Push [source](https://docs.coveo.com/en/246/) that doesn't populate the `permanentid` [field](https://docs.coveo.com/en/200/) with [metadata](https://docs.coveo.com/en/218/), use `"urihash"`. *** `` (string) is the value of the [field](https://docs.coveo.com/en/200/) whose name was specified in ``. > **Leading practice** > > Use the `raw.permanentid` value of the clicked [query](https://docs.coveo.com/en/231/) result [item](https://docs.coveo.com/en/210/). > > If this is unavailable, use the `raw.urihash` value of the clicked [query](https://docs.coveo.com/en/231/) result [item](https://docs.coveo.com/en/210/). -- ** Set other required or optional properties as needed, such as `language`, `[originLevel1](https://docs.coveo.com/en/1337/)`, or `[originLevel2](https://docs.coveo.com/en/1338/)`. . When the Usage Analytics Write API returns, redirect the client as appropriate, using the `clickableUri` value of the clicked [query](https://docs.coveo.com/en/231/) result [item](https://docs.coveo.com/en/210/). ### Examples of opening query results . Logging a `documentOpen` click [event](https://docs.coveo.com/en/260/): ```http POST https://myorganizationid9sd8df7s.analytics.org.coveo.com/rest/ua/v15/analytics/click?visitor=28s6g49d-f81s-1435-2r5x153dle72 HTTP/1.1 ​ Accept: application/json Content-Type: application/json Authorization: Bearer **********-****-****-****-************ ``` **Payload (excerpt)** ```json { ... "anonymous": false, "actionCause": "documentOpen", "customData":{ "contentIdKey": "permanentid", "contentIdValue": "648a63d6a19545297692b4ae41a7d5e947c711be5f3c23dff69af3106960", "author": "Fyodor Dostoyevsky", "documentTitle": "The Brothers Karamazov", "documentURL": "https://example.com/books/the-brothers-karamazov" }, "documentPosition": 1, "documentTitle": "The Brothers Karamazov", "documentUrl": "https://example.com/books/the-brothers-karamazov", "language": "en", "originLevel1": "BookstoreSearch", "originLevel2": "All", "searchQueryUid": "7bfc652a-9dea-4811-b3f9-6d24345c37ce", "sourceName": "example.com", ... } ``` . Logging a `recommendationOpen` click [event](https://docs.coveo.com/en/260/): ```http POST https://myorganizationid9sd8df7s.analytics.org.coveo.com/rest/ua/v15/analytics/click?visitor=28s6g49d-f81s-1435-2r5x153dle72 HTTP/1.1 ​ Accept: application/json Content-Type: application/json Authorization: Bearer **********-****-****-****-************ ``` **Payload (excerpt)** ```json { ... "anonymous": false, "actionCause": "recommendationOpen", "customData":{ "contentIdKey": "permanentid", "contentIdValue": "8asd8f7a9sfd8asfdasf78afsdh8h87h878g37g872gf8g83gf78g2f387g2", "author": "Ivan Turgenev", "documentTitle": "Fathers and Sons", "documentURL": "https://example.com/books/fathers-and-sons" }, "documentPosition": 2, "documentTitle": "Fathers and Sons", "documentUrl": "https://example.com/books/fathers-and-sons", "language": "en", "originLevel1": "BookstoreRecommendation", "originLevel2": "", "searchQueryUid": "b2d60d3f-b2cf-4018-bfd2-8094d24fa8e9", "sourceName": "example.com", ... } ``` ### Preview a result > **Notes** > > * As a reference, you may want to look at the source code of the [`Quickview`](https://coveo.github.io/search-ui/components/quickview.html) component to see how it's implemented in the [Coveo JavaScript Search Framework](https://docs.coveo.com/en/187/). > > * Unlike most other Search API requests in this guide, preview requests are made using the GET endpoint rather than POST. When the user previews a [query](https://docs.coveo.com/en/231/) result [item](https://docs.coveo.com/en/210/), such as by clicking **Preview**: . Prepare a GET request to `https://.org.coveo.com/rest/search/v2/html?uniqueId=`, where `` is the unique identifier of your [organization](https://docs.coveo.com/en/185/). In the [query](https://docs.coveo.com/en/231/) string, set `` to the `raw.uniqueId` value of the [query](https://docs.coveo.com/en/231/) result [item](https://docs.coveo.com/en/210/) to preview. > **Leading practice** > > Although only the `uniqueId` parameter is required when requesting an HTML document from the Search API, you should send all the parameters that were originally included in the search request that returned the [item](https://docs.coveo.com/en/210/) to preview. > This allows the Search API to highlight relevant terms in the HTML response. . Call the Search API to [execute the query](https://docs.coveo.com/en/1445/) prepared in step 1. When the Search API returns: .. Call the Usage Analytics Write API to [log the corresponding click event](https://docs.coveo.com/en/2064/). In the request body: *** Set the `actionCause` property to `documentQuickview`. *** Include the following key-value pairs (if available) in the `[customData](https://docs.coveo.com/en/1341/)` property: -- **** `"author": ` **** `"contentIdKey": ` **** `"contentIdValue": ` **** `"documentTitle": ` **** `"documentUrl": ` -- where: -- **** `` (string) is the `raw.author` value of the clicked [query](https://docs.coveo.com/en/231/) result [item](https://docs.coveo.com/en/210/). This can be an empty string. **** `` (string) is the name of a [field](https://docs.coveo.com/en/200/) which uniquely and permanently identifies the clicked [item](https://docs.coveo.com/en/210/). > **Leading practice** > > Use [`"permanentid"`](https://docs.coveo.com/en/1913/). > > If this is unavailable, such as if the clicked [item](https://docs.coveo.com/en/210/) resides in a Push [source](https://docs.coveo.com/en/246/) that doesn't populate the `permanentid` [field](https://docs.coveo.com/en/200/) with [metadata](https://docs.coveo.com/en/218/), use `"urihash"`. **** `` (string) is the value of the [field](https://docs.coveo.com/en/200/) whose name was specified in ``. > **Leading practice** > > Use the `raw.permanentid` value of the clicked [query](https://docs.coveo.com/en/231/) result [item](https://docs.coveo.com/en/210/). > > If this is unavailable, use the `raw.urihash` value of the clicked [query](https://docs.coveo.com/en/231/) result [item](https://docs.coveo.com/en/210/). **** `` (string) is the `title` value of the clicked [query](https://docs.coveo.com/en/231/) result [item](https://docs.coveo.com/en/210/). **** `` (string) is the `uri` value of the clicked [query](https://docs.coveo.com/en/231/) result [item](https://docs.coveo.com/en/210/). -- *** Set other required or optional properties as needed, such as `language`, `[originLevel1](https://docs.coveo.com/en/1337/)`, or `[originLevel2](https://docs.coveo.com/en/1338/)`. .. Render the HTML document. #### Examples of previewing a result . Requesting a `Preview`: ```http GET https://myorganizationid9sd8df7s.org.coveo.com/rest/search/v2/html?uniqueId=The_Brothers_Karamazov_Unique_Id&locale=en-US&q=karamazov&searchHub=BookstoreSearch&tab=All HTTP/1.1 ​ Authorization: Bearer **********-****-****-****-************ ``` **200 OK response (excerpt)** ```html ...

The Brothers Karamazov is a passionate philosophical novel set in 19-th century Russia, that enters ...

... ``` . Logging a `documentQuickview` click [event](https://docs.coveo.com/en/260/): ```http POST https://myorganizationid9sd8df7s.analytics.org.coveo.com/rest/ua/v15/analytics/click?visitor=28s6g49d-f81s-1435-2r5x153dle72 HTTP/1.1 ​ Accept: application/json Content-Type: application/json Authorization: Bearer **********-****-****-****-************ ``` **Payload (excerpt)** ```json { ... "anonymous": false, "actionCause": "documentQuickview", "customData":{ "contentIdKey": "permanentid", "contentIdValue": "648a63d6a19545297692b4ae41a7d5e947c711be5f3c23dff69af3106960", "author": "Fyodor Dostoyevsky", "documentTitle": "The Brothers Karamazov", "documentURL": "https://example.com/books/the-brothers-karamazov" }, "documentPosition": 1, "documentTitle": "The Brothers Karamazov", "documentUrl": "https://example.com/books/the-brothers-karamazov", "language": "en", "originLevel1": "BookstoreSearch", "originLevel2": "All", "searchQueryUid": "7bfc652a-9dea-4811-b3f9-6d24345c37ce", "sourceName": "example.com", ... } ``` ## Page query results > **Note** > > As a reference, you may want to look at the source code of the [`Pager`](https://coveo.github.io/search-ui/components/pager.html) component to see how it's implemented in the [Coveo JavaScript Search Framework](https://docs.coveo.com/en/187/). By default, the `results` array of a [query](https://docs.coveo.com/en/231/) response contains the first ten [items](https://docs.coveo.com/en/210/) that match the [query](https://docs.coveo.com/en/231/), according to the specified [sort criteria](#sort-query-results). However, you may want to allow users to navigate to a specific page of [query](https://docs.coveo.com/en/231/) results or modify the default page size in your result list implementation. Paging [query](https://docs.coveo.com/en/231/) results involves the following search request parameters: * `firstResult` (unsigned integer) * `numberOfResults` (unsigned integer) The Search API will return `numberOfResults` (for example, `50`) [items](https://docs.coveo.com/en/210/), starting from the 0-based [index](https://docs.coveo.com/en/204/) position of the specified `firstResult` (for example, `10`). When the user changes the page number of the result list, such as by clicking a different page number, an arrow, or a button to modify the number of results per page: . Prepare a new [query](https://docs.coveo.com/en/231/). Ensure that the `firstResult` and/or `numberOfResults` search request parameters are set to the desired values. . Call the Search API to [execute the query](https://docs.coveo.com/en/1445/) prepared in step 1. When the Search API returns: .. Call the Usage Analytics Write API to [log the corresponding custom event](https://docs.coveo.com/en/2650/). In the request body: *** Set the `eventType` property to `getMoreResults`. *** Set the `eventValue` property to: **** `pagerNumber` if the user has selected a specific page. **** `pagerNext` if the user has selected the next page. **** `pagerPrevious` if the user has selected the previous page. **** `pagerScrolling` if the user has scrolled down to the bottom of the result list (for example, in infinite scroll mode) and an additional "page" of [query](https://docs.coveo.com/en/231/) results needs to be loaded. **** `pagerResize` if the user has selected a different number of results to display per page. *** Include one of the following key-value pairs in the `[customData](https://docs.coveo.com/en/1341/)` property, depending on the specified `eventValue`: -- **** `"pagerNumber": ` if `eventValue` is set to `pagernext`, `pagerPrevious`, or `pagerNumber`. **** `"currentResultsPerPage": ` if `eventValue` is set to `pagerResize`. -- where: -- **** `` (unsigned integer) is the new page number (for example, `2`). **** `` (unsigned integer) is the new number of results per page (for example, `50`). -- > **Note** > > No `[customData](https://docs.coveo.com/en/1341/)` is required if `eventValue` is set to `pagerScrolling`. *** Set other required or optional properties as needed, such as `language`, `[originLevel1](https://docs.coveo.com/en/1337/)`, or `[originLevel2](https://docs.coveo.com/en/1338/)`. .. [Render the query results](#render-query-results). ### Examples of paging query results . Executing a search [query](https://docs.coveo.com/en/231/) when the user, who is currently on page `1`, which contains `10` results, selects page `3`: ```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 { ... "firstResult": 20, "locale": "en-US", "searchHub": "BookstoreSearch", "tab": "All", ... } ``` **200 OK response body (excerpt)** ```json { ... "results": [ ...data to render the result list... ], "totalCount": 36, ... } ``` . Logging a `pagerNumber` custom [event](https://docs.coveo.com/en/260/) for the previous action: ```http POST https://myorganizationid9sd8df7s.analytics.org.coveo.com/rest/ua/v15/analytics/custom?visitor=28s6g49d-f81s-1435-2r5x153dle72 HTTP/1.1 ​ Accept: application/json Content-Type: application/json Authorization: Bearer **********-****-****-****-************ ``` **Payload (excerpt)** ```json { ... "anonymous": false, "customData": { "pagerNumber": "3" }, "eventType": "getMoreResults", "eventValue": "pagerNumber", "language": "en", "originLevel1": "BookstoreSearch", "originLevel2": "All", ... } ``` ## Sort query results > **Note** > > As a reference, you may want to look at the source code of the [`Sort`](https://coveo.github.io/search-ui/components/sort.html) component to see how it's implemented in the [Coveo JavaScript Search Framework](https://docs.coveo.com/en/187/). The Search API [`sortCriteria`](https://docs.coveo.com/en/13#operation/searchUsingPost-sortCriteria) [query](https://docs.coveo.com/en/231/) parameter specifies how results are sorted. This parameter has five possible values which you may want to offer as options to your users: * `relevancy`: Use [index](https://docs.coveo.com/en/204/) ranking factors or weights as well as specified [query ranking expressions (QREs)](https://docs.coveo.com/en/1472/) and [query ranking functions (QRFs)](https://docs.coveo.com/en/237/) to compute a ranking `score` for each [item](https://docs.coveo.com/en/210/), and sort the results in descending order. * `date ascending`/`date descending`: Use the `@date` [field](https://docs.coveo.com/en/200/) to sort the results in the specified order. This [field](https://docs.coveo.com/en/200/) typically contains the last modification date of each [item](https://docs.coveo.com/en/210/) in the [index](https://docs.coveo.com/en/204/). * `qre`: Use only [QREs](https://docs.coveo.com/en/1472/) and [QRFs](https://docs.coveo.com/en/237/) to compute a ranking `score` for each [item](https://docs.coveo.com/en/210/), and sort the results in descending order. This is similar to `relevancy`, except that [index](https://docs.coveo.com/en/204/) ranking factors and weights aren't computed. * `nosort`: Don't sort the results. The [index](https://docs.coveo.com/en/204/) will return the results in an indeterminate order. * `@ ascending`/`@ descending`: Use the value of a custom, sortable [field](https://docs.coveo.com/en/200/) to sort the results in the specified order. `` represents a result [item](https://docs.coveo.com/en/210/) [field](https://docs.coveo.com/en/200/) name. > **Notes** > > * When `@ ascending`/`@ descending` is used, the `` it's based on must have its [`sort`](https://docs.coveo.com/en/8#tag/Fields/operation/createField-sort) option set to `true`. > > * It's possible to combine zero or one date criterion with one or more [field](https://docs.coveo.com/en/200/) sort criteria by separating them with commas (for example, `date ascending,@views descending,@likes descending`). By default, `sortCriteria` is set to `relevancy`, meaning that [query](https://docs.coveo.com/en/231/) result [items](https://docs.coveo.com/en/210/) are sorted by their ranking `score` values, which are computed by the [index](https://docs.coveo.com/en/204/). These `score` values are based on several ranking factors and weights, such as the proximity of [query](https://docs.coveo.com/en/231/) terms to one another or the term frequency-inverse document frequency. They can also be influenced by other means such as [QREs](https://docs.coveo.com/en/1472/) and [QRFs](https://docs.coveo.com/en/237/), [Coveo ML](https://docs.coveo.com/en/188/) [ART](https://docs.coveo.com/en/1013/) and [CR](https://docs.coveo.com/en/1016/) [models](https://docs.coveo.com/en/1012/), and certain types of [query pipeline statements](https://docs.coveo.com/en/236/). When the user chooses a different `sortCriteria` or sort order for the [query](https://docs.coveo.com/en/231/) results, such as by selecting a value in a **Sort By** widget: . Prepare a new [query](https://docs.coveo.com/en/231/). Ensure that the `sortCriteria` search request parameter is set to the desired value. . Call the Search API to [execute the query](https://docs.coveo.com/en/1445/) prepared in step 1. When the Search API returns: .. Call the Usage Analytics Write API to [log the corresponding search event](https://docs.coveo.com/en/1502/). In the request body: *** Set the `actionCause` property to `resultsSort`. *** Include the following key-value pair in the `[customData](https://docs.coveo.com/en/1341/)` property: -- **** `"resultsSortBy": ` -- where: -- **** `` (string) is the new `sortCriteria` or sort order, in lowercase and without spaces. For example, `dateascending,@sizeascending` instead of `date ascending,@size ascending`. -- *** Set other required or optional properties as needed, such as `language`, `[originLevel1](https://docs.coveo.com/en/1337/)`, or `[originLevel2](https://docs.coveo.com/en/1338/)`. .. [Render the query results](#render-query-results). ### Example of sorting query results . Executing a search [query](https://docs.coveo.com/en/231/) when the user selects `Date Descending`: ```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 { ... "locale": "en-US", "q": "tolstoy", "searchHub": "BookstoreSearch", "sortCriteria": "Date Descending", "tab": "All", ... } ``` **200 OK response body (excerpt)** ```json { ... "duration": 105, "searchUid": "7bfc652a-9dea-4811-b3f9-6d24345c37ce", "results": [ { ... "title":"The 19th Century", "raw": { ... "date":1375187019000, ... }, ... }, { ... "title":"War and Peace", "raw": { ... "date":1375189132000, ... }, ... }, { ... "title":"Russian literature for Dummies", "raw": { ... "date":1384880103000, ... }, ... }, ... ], "totalCount": 403, ... } ``` . Logging a `resultsSort` search [event](https://docs.coveo.com/en/260/) for the previous action: ```http POST https://myorganizationid9sd8df7s.analytics.org.coveo.com/rest/ua/v15/analytics/search HTTP/1.1 ​ Accept: application/json Content-Type: application/json Authorization: Bearer **********-****-****-****-************ ``` **Payload (excerpt)** ```json { ... "actionCause": "resultsSort", "anonymous": false, "customData": { "resultsSortBy": "dateascending" }, "language": "en", "originLevel1": "BookstoreSearch", "originLevel2": "All", "queryText": "tolstoy", "responseTime": 105, "searchQueryUid": "7bfc652a-9dea-4811-b3f9-6d24345c37ce", ... } ``` ## Switch result list layouts > **Note** > > As a reference, you may want to look at the source code of the [`ResultLayoutSelector`](https://coveo.github.io/search-ui/components/resultlayoutselector.html) component to see how it's implemented in the [Coveo JavaScript Search Framework](https://docs.coveo.com/en/187/). When the user chooses a different result list layout, such as by making a selection in a **Layout** widget: . Call the Usage Analytics Write API to [log the corresponding custom event](https://docs.coveo.com/en/2650/). In the request body: ** Set the `eventType` property to `resultsLayout`. ** Set the `eventValue` property to `changeResultsLayout`. ** Include the following key-value pair in the `customData` property: -- *** `"resultsLayoutChangeTo": ` -- where: -- *** `` (string) is the identifier of the newly selected result list layout. The [Coveo JavaScript Search Framework](https://docs.coveo.com/en/187/) uses the `list`, `card`, and `table` values. -- . [Render the result list](#render-query-results) with the new layout. > **Note** > > In the [Coveo JavaScript Search Framework](https://docs.coveo.com/en/187/), [query](https://docs.coveo.com/en/231/) results are rendered using a different set of result templates for each result list layout (list, card, and table). ### Example of switching result list layouts Logging a `changeResultsLayout` custom [event](https://docs.coveo.com/en/260/) when the user selects the `list` display: ```http POST https://myorganizationid9sd8df7s.analytics.org.coveo.com/rest/ua/v15/analytics/custom?visitor=28s6g49d-f81s-1435-2r5x153dle72 HTTP/1.1 ​ Accept: application/json Content-Type: application/json Authorization: Bearer **********-****-****-****-************ ``` **Payload (excerpt)** ```json { ... "anonymous": false, "customData": { "resultsLayoutChangeTo": "list" }, "eventType": "resultsLayout", "eventValue": "changeResultsLayout", "language": "en", "originLevel1": "BookstoreSearch", "originLevel2": "All", ... } ``` ## Handle folded results > **Note** > > As a reference, you may want to look at the source code of the [`Folding`](https://coveo.github.io/search-ui/components/folding.html) component to see how it's implemented in the [Coveo JavaScript Search Framework](https://docs.coveo.com/en/187/). A [search interface](https://docs.coveo.com/en/2741/) sometimes supports the [folding](https://docs.coveo.com/en/1466/) of related [query](https://docs.coveo.com/en/231/) result [items](https://docs.coveo.com/en/210/). There are two possible folding actions, the first of which groups [items](https://docs.coveo.com/en/210/) together. The second action, which builds upon the first, orders the grouped [items](https://docs.coveo.com/en/210/) in logical parent-child relationships. Implementing the first action requires setting the `filterField` Search API parameter to `@`, where `` is the name of the [field](https://docs.coveo.com/en/200/) to use for grouping. Upon receiving this request, the Search API sends back a list of result [items](https://docs.coveo.com/en/210/), where each [item](https://docs.coveo.com/en/210/) contains a `childResults` array of results which have the same `` value. The `childResults` arrays are sorted using the `sortCriteria`, and their maximum length is `filterFieldRange` (the default value is `5`). To implement the second action, provide additional `parentField` and `childField` parameters in your Search API request, where the `parentField` value must uniquely identify each [item](https://docs.coveo.com/en/210/) and the `childField` value is the value of the parent `parentField`. When the Search API sends back a list of result [items](https://docs.coveo.com/en/210/), the [items](https://docs.coveo.com/en/210/) in the `childResults` arrays will also have a `parentResult` [field](https://docs.coveo.com/en/200/), which can be used to resolve parent-child relationships within each folded [query](https://docs.coveo.com/en/231/) result. > **Notes** > > * The Search API doesn't necessarily return the result list in the logical parent-child ordering. > You'll likely need to write client-side logic to resolve the parent-child relationships within each folded [query](https://docs.coveo.com/en/231/) result, using one or both of the preceding properties. > > * Result folding and [duplicate filtering](https://docs.coveo.com/en/13#operation/searchUsingPost-enableDuplicateFiltering) are mutually exclusive. When a new [query](https://docs.coveo.com/en/231/) is made in a [search interface](https://docs.coveo.com/en/2741/) that supports folding: . Prepare a new [query](https://docs.coveo.com/en/231/). Ensure that `filterField`, and potentially `parentField`, `childField`, and `filterFieldRange`, are set to the desired values. . Call the Search API to [execute the query](https://docs.coveo.com/en/1445/) prepared in step 1. When the Search API returns: .. Call the Usage Analytics Write API to [log the corresponding search event](https://docs.coveo.com/en/1502/). .. Render the folded result list. In addition to the standard properties to use when [rendering query result](#render-query-results) [items](https://docs.coveo.com/en/210/), the [search interface](https://docs.coveo.com/en/2741/) needs to use the `childResults` [field](https://docs.coveo.com/en/200/) to display [items](https://docs.coveo.com/en/210/) which belong to the same group and, if necessary, the `parentResult` [field](https://docs.coveo.com/en/200/) to resolve parent-child relationships. ### Examples of handling folded results . A bookstore [search interface](https://docs.coveo.com/en/2741/) implements the first folding action to group books by series. [indexed](https://docs.coveo.com/en/204/) [items](https://docs.coveo.com/en/210/) contain a `bookseriesid` [field](https://docs.coveo.com/en/200/) that identifies the series to which each [item](https://docs.coveo.com/en/210/) belongs. When the user queries `"solzhenitsyn"`, the [search interface](https://docs.coveo.com/en/2741/) sends the following request to the Search API: ```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 { ... "locale": "en-US", "q": "solzhenitsyn", "filterField":"@bookseriesid", "searchHub": "BookstoreSearch", "tab": "All", ... } ``` **200 OK response body (excerpt)** ```json { ... "results": [ { ... "title": "The Gulag Archipelago, Vol. 2", "raw": { ... "bookseriesid":"GulagArchipelagoHarperClassics", ... }, ... "childResults": [ { "title": "The Gulag Archipelago, Vol. 1", "raw": { ... "bookseriesid":"GulagArchipelagoHarperClassics", ... }, ... }, { "title": "The Gulag Archipelago, Vol. 3", "raw": { ... "bookseriesid":"GulagArchipelagoHarperClassics", ... }, ... }, ], ... }, { ... "title": "One Day in the Life of Ivan Denisovich", "raw": { ... "bookseriesid":"OneDayLifeIvanDenisovichSignetClassics", ... }, ... "childResults": [], ... }, ... ], ... } ``` As you can see in the preceding [query](https://docs.coveo.com/en/231/) response, the Search API returns a list of [items](https://docs.coveo.com/en/210/) grouped by `bookseriesid`. The results are sorted by relevance (this applies to both the `results` and `childResults` arrays). Also, when a book series only contains one [item](https://docs.coveo.com/en/210/), its `childResults` array is empty. . A bookstore [search interface](https://docs.coveo.com/en/2741/) implements both folding actions to group books by series as well as order them in logical parent-child relationships. [indexed](https://docs.coveo.com/en/204/) [items](https://docs.coveo.com/en/210/) contain a `bookseriesid` [field](https://docs.coveo.com/en/200/) that identifies the series to which each [item](https://docs.coveo.com/en/210/) belongs. They also contain a `bookid` [field](https://docs.coveo.com/en/200/) that uniquely identifies each book within its series, if applicable, and a `parentbookid` that indicates the `bookid` of the parent book, if applicable. When the user queries `"solzhenitsyn"`, the [search interface](https://docs.coveo.com/en/2741/) sends the following request to the Search API: ```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 { ... "locale": "en-US", "q": "solzhenitsyn", "filterField":"@bookseriesid", "parentField":"@bookid", "childField":"@parentbookid", "searchHub": "BookstoreSearch", "sortCriteria": "Date Descending", "tab": "All", ... } ``` **200 OK response body (excerpt)** ```json { ... "results": [ { ... "title": "The Gulag Archipelago, Vol. 2", "raw": { ... "bookseriesid":"GulagArchipelagoHarperClassics", "bookid":"GulagArchipelagoHarperClassics2", "parentbookid":"GulagArchipelagoHarperClassics1", ... }, ... "childResults": [ { "title": "The Gulag Archipelago, Vol. 1", "raw": { ... "bookseriesid":"GulagArchipelagoHarperClassics", "bookid":"GulagArchipelagoHarperClassics1", "parentbookid":"GulagArchipelagoHarperClassics1", ... }, ... }, { "title": "The Gulag Archipelago, Vol. 3", "raw": { ... "bookseriesid":"GulagArchipelagoHarperClassics", "bookid":"GulagArchipelagoHarperClassics3", "parentbookid":"GulagArchipelagoHarperClassics1", ... }, ... }, ], ... }, { ... "title": "One Day in the Life of Ivan Denisovich", "raw": { ... "bookseriesid":"OneDayLifeIvanDenisovichSignetClassics", ... }, ... "childResults": [], ... }, ... ], ... } ``` As you can see in the preceding [query](https://docs.coveo.com/en/231/) response, the Search API returns a list of [items](https://docs.coveo.com/en/210/) grouped by `bookseriesid`. The results are sorted by relevance (this applies to both the `results` and `childResults` arrays), and the `bookid` and `parentbookid` [fields](https://docs.coveo.com/en/200/) are required to resolve the logical ordering. Also, when a book series only contains one [item](https://docs.coveo.com/en/210/), its `childResults` array is empty and its `parentField` and `childField` [fields](https://docs.coveo.com/en/200/) don't need to be populated. ## Export results > **Note** > > As a reference, you may want to look at the source code of the [`ExportToExcel`](https://coveo.github.io/search-ui/components/exporttoexcel.html) component to see how it's implemented in the [Coveo JavaScript Search Framework](https://docs.coveo.com/en/187/). A [search interface](https://docs.coveo.com/en/2741/) sometimes offers the possibility to export the result list in Excel or OpenSearch format. When the user chooses to export the result list, such as by clicking **Export to Excel**: . Prepare a new [query](https://docs.coveo.com/en/231/). Ensure that the `format` property is set to: ** `opensearch-atom` or `opensearch-rss` if the user selected an OpenSearch format. ** `xlsx` if the user selected the Excel format. . Call the Search API to [execute the query](https://docs.coveo.com/en/1445/) prepared in step 1. When the Search API returns: .. If `format` is set to `xlsx`, call the Usage Analytics Write API to [log the corresponding custom event](https://docs.coveo.com/en/2650/). In the request body: -- *** Set the `eventType` property to `misc`. *** Set the `eventValue` property to `exportToExcel`. -- > **Note** > > The [Coveo JavaScript Search Framework](https://docs.coveo.com/en/187/) doesn't currently support exporting in XML format. > As a result, if the user chooses to export to XML, there are currently no precise guidelines to follow when logging the corresponding [event](https://docs.coveo.com/en/260/). .. Generate a download link for the user. ### Examples of exporting results . Executing a search [query](https://docs.coveo.com/en/231/) when the user clicks **Export to Excel**: ```http POST https://myorganizationid9sd8df7s.org.coveo.com/rest/search/v2 HTTP/1.1 ​ Content-Type: application/json Authorization: Bearer **********-****-****-****-************ ``` **Payload (excerpt)** ```json { ... "format": "xlsx", ... } ``` . Logging an `exportToExcel` custom [event](https://docs.coveo.com/en/260/) for the previous action: ```http POST https://myorganizationid9sd8df7s.analytics.org.coveo.com/rest/ua/v15/analytics/custom?visitor=28s6g49d-f81s-1435-2r5x153dle72 HTTP/1.1 ​ Accept: application/json Content-Type: application/json Authorization: Bearer **********-****-****-****-************ ``` **Payload (excerpt)** ```json { ... "anonymous": false, "eventType": "misc", "eventValue": "exportToExcel", "language": "en", "originLevel1": "BookstoreSearch", "originLevel2": "All", ... } ``` ## Toggle a facet value from a result list item In some result lists, [query](https://docs.coveo.com/en/231/) result [items](https://docs.coveo.com/en/210/) contain clickable [fields](https://docs.coveo.com/en/200/) which the user can toggle to [filter](https://docs.coveo.com/en/2736/) the entire result list (that is, to select or deselect a [facet](https://docs.coveo.com/en/198/) value). When the user clicks a result list [item](https://docs.coveo.com/en/210/) [field](https://docs.coveo.com/en/200/), such as the `salesforce` [field](https://docs.coveo.com/en/200/): . Prepare a new [query](https://docs.coveo.com/en/231/). This is the same as the [query](https://docs.coveo.com/en/231/) that's sent when selecting or deselecting the associated [facet](https://docs.coveo.com/en/198/) value (see [Toggle facet values](https://docs.coveo.com/en/3199#toggle-facet-values)). . Call the Search API to [execute the query](https://docs.coveo.com/en/1445/) prepared in step 1. When the Search API returns: .. Call the Usage Analytics Write API to [log the corresponding search event](https://docs.coveo.com/en/1502/). In the request body: *** Set the `actionCause` property to `documentField`. *** Include the following key-value pairs in the `[customData](https://docs.coveo.com/en/1341/)` property: -- **** `"facetField": ` **** `"facetId": ` **** `"facetValue": ` -- where: -- **** `` (string) is the `@`-prefixed name of the [field](https://docs.coveo.com/en/200/) on which the toggled [facet](https://docs.coveo.com/en/198/) is based (for example, `@tags`). **** `` (string) is the unique identifier of the toggled [facet](https://docs.coveo.com/en/198/). Typically, this is the name of the [field](https://docs.coveo.com/en/200/) that this [facet](https://docs.coveo.com/en/198/) is based on (for example, `@tags`). **** `` (string) is the value of the [field](https://docs.coveo.com/en/200/) selected by the user (for example, `salesforce`). -- *** Set other required or optional properties as needed, such as `language`, `[originLevel1](https://docs.coveo.com/en/1337/)`, or `[originLevel2](https://docs.coveo.com/en/1338/)`. .. Update the [facet](https://docs.coveo.com/en/198/) instance. .. [Render the query results](#render-query-results). ### Examples of toggling a facet value from a result list item . Executing a search [query](https://docs.coveo.com/en/231/) when the user selects the `salesforce` [item](https://docs.coveo.com/en/210/) [field](https://docs.coveo.com/en/200/): ```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 { ... "aq": "(@tags==("salesforce"))", "locale": "en-US", "q": "coveo", "searchHub": "ExternalSearch", "tab": "All", ... } ``` **200 OK response body (excerpt)** ```json { ... "duration": 247, "searchUid": "de6cb58a-2abb-4718-a874-cc2162691cd9", "results": [ ...data to render the result list... ], "totalCount": 272, ... } ``` . Logging a `documentField` search [event](https://docs.coveo.com/en/260/) for the previous action: ```http POST https://myorganizationid9sd8df7s.analytics.org.coveo.com/rest/ua/v15/analytics/search HTTP/1.1 ​ Accept: application/json Content-Type: application/json Authorization: Bearer **********-****-****-****-************ ``` **Payload (excerpt)** ```json { ... "actionCause": "documentField", "anonymous": false, "customData": { "facetField": "@tags", "facetId": "@tags", "facetValue": "salesforce" }, "language": "en", "originLevel1": "ExternalSearch", "originLevel2": "All", "queryText": "coveo", "responseTime": 247, "searchQueryUid": "de6cb58a-2abb-4718-a874-cc2162691cd9", ... } ```