Custom query suggestions

This is for:


There are several ways to add query suggestions to your search box. The simplest is to use pre-built Coveo Atomic components such as atomic-search-box-recent-queries and atomic-search-box-query-suggestions. Another way is to use your own custom suggestions. This article shows you how to do so. This could be useful, for example, if you want to retrieve suggestions from an API external to the Coveo Platform.

For custom suggestions to integrate well with existing Atomic components, the Atomic library offers a function called dispatchSearchBoxSuggestionsEvent. You can take a look at the usage of this function, along with the relevant reference documentation, in the following sections.

Complete code example

The following code sample shows you how to leverage dispatchSearchBoxSuggestionsEvents to provide custom query suggestions returned from a third-party API. You can copy-paste it, as is, to start playing with the concepts discussed in this article.

<!DOCTYPE html>
        <title>Custom query suggestions</title>
        <script type="module" src=""></script>
        <link rel="stylesheet" href=""/>
        <script type="module">
            import {dispatchSearchBoxSuggestionsEvent} from '';

            function registerCustomSuggestions() {
              class CustomSuggestions extends HTMLElement {
                constructor() {

                suggestions = [];

                renderSuggestions(bindings) { 4
                  return this.suggestions.slice(0, 2).map((suggestion) => {
                    const content = document.createElement('div');
                    content.innerText = suggestion;
                    return {
                      key: suggestion,
                      query: suggestion,
                      onSelect: () => {

                onInput(bindings) { 3
                  const query = bindings.searchBoxController.state.value;

                  return fetch('')
                    .then((res) => res.json())
                    .then((res) => {
                      const resultsWithQuery = query ? results.filter((r) =>[0])) : results;
                      this.suggestions = resultsWithQuery.slice(0, 10).map((r) =>;

                async connectedCallback() {
                  dispatchSearchBoxSuggestionsEvent((bindings) => { 1
                    return { 2
                      position: 2,
                      onInput: () => this.onInput(bindings),
                      renderItems: () => this.renderSuggestions(bindings),
                  }, this);

              window.customElements.define('custom-suggestions', CustomSuggestions); 5

            async function main() {
              await customElements.whenDefined('atomic-search-interface');
              const searchInterface = document.querySelector('atomic-search-interface');
              await searchInterface.initialize({
                accessToken: '<ACCESS_TOKEN>',
                organizationId: '<ORGANIZATION_ID>',
                organizationEndpoints: await searchInterface.getOrganizationEndpoints('<ORGANIZATION_ID>'),

              const engine = searchInterface.engine;

        <atomic-search-interface id="search">
            <atomic-layout-section section="search">
                  <custom-suggestions></custom-suggestions> 6
            <atomic-layout-section section="main">
                <atomic-layout-section section="results">
1 Pass bindings as input for the SearchBoxSuggestionsEvent callback.
2 The callback function needs to return a SearchBoxSuggestions object with certain required properties, as detailed in the reference section.
3 onInput accesses the current query by using the state of the searchBoxController. It then makes a call to an API outside of the Coveo Platform and returns a list of matching results if they included the current query. These results are saved to be provided as suggestions.
4 The results saved from the previous step are processed and converted into a SearchBoxSuggestionElement object with a unique key, the query to be suggested, and the HTML content to be displayed for the suggestions. In addition to these, an onSelect callback is defined so that whenever the suggestion is selected by the user, the search box display text is updated and a search query is triggered.
5 A new custom HTML element is defined based on the CustomSuggestions class.
6 The newly defined custom element can be placed as a child of the <atomic-search-box> component to provide custom QS.


Take a look at the Atomic project repository for more information about the data types and methods detailed here.


Dispatches an event which retrieves the SearchBoxSuggestionsBindings on a configured parent search box.


  • event: SearchBoxSuggestionsEvent (required)

    The event sent from the registered query suggestions to the parent search box.

  • element: HTMLElement (required)

    Element on which to dispatch the event, which must be the child of a configured search box.

Returns void


The event sent from the registered QS to the parent search box.



Element which will be rendered in the list of suggestions.

Property Description Type

key (required)

Stable identity which enables Stencil to reuse DOM elements for better performance. The best way to pick a key is to use a string that uniquely identifies that list item among its siblings (often your data will already have IDs).


content (required)

Rendered content of the element.

Element | VNode


Hook called when the selection is selected.

(e: Event) ⇒ void


The query associated with the suggestion which will replace the query in the search box if the suggestion is selected.



For improved accessibility, provide this property with additional information. See Aria Label.



Adds a specific shadow part attribute that can be selected with the CSS ::part pseudo-element.



Hide the suggestion if it’s the last in the list.



List of suggestions that will be displayed along with other lists (e.g recent queries) when the search box’s input is selected. This will contain a list of SearchBoxSuggestionElement objects.

Property Description Type

position (required)

The search box will sort the position of suggestions using this value. The lowest value being first. Atomic provided suggestions, by default, use the DOM.



Whether the suggestions should be listed in the right or left panel. By default, the suggestions are listed in the left panel.


renderItems (required)

Method that returns the list of elements which will be rendered in the list of suggestions.

() ⇒ SearchBoxSuggestionElement[];


Hook called when the user changes the search box’s input value. This can lead to all the QS being updated.

() ⇒ Promise<unknown> | void


Hook called when the suggested query changes as a user traverses through the list of suggestions. This is used for instant results, which are rendered based on the current suggested query.

(q: string) ⇒ Promise<unknown> | void


The bindings passed from the search box to the suggestions. This object gives you access to the state of the suggestion system as a whole and has important information and functions that you can invoke.

Property Description Type


The unique ID of the search box.



Whether the search box is standalone.



The search box headless controller.



The amount of queries displayed when the user interacts with the search box. This is a property set on the atomic-search-box component.



Whether to clear all active query filters when the user submits a new query from the search box.



Retrieves the suggested query, meaning the query that would be sent if the search were executed. The suggested query changes as a user traverses through the list of suggestions.

() ⇒ string


Removes the current suggestions.

() ⇒ void


Triggers update & retrieval of all suggestions.

() ⇒ void


Retrieves the current suggestions.

() ⇒ SearchBoxSuggestions[]


Retrieves the currently suggested elements.

() ⇒ SearchBoxSuggestionElement[]