Providing Search Box Suggestions

The JavaScript Search Framework supports different kinds of search box suggestions:

Providing Coveo Machine Learning Query Suggestions

The Coveo Machine Learning (Coveo ML) Query Suggestions (QS) feature can recommend contextually relevant queries based on previously recorded usage analytics data.

Query Suggestions Example

To leverage this feature in a search interface:

  1. Use the Searchbox component to initialize an Omnibox.

    Unless you are configuring a standalone search box, you should also initialize an Analytics component.

    <div id="search" class="CoveoSearchInterface">
      <div class="CoveoAnalytics" data-search-hub="CommunitySearch"></div>
      <div class="coveo-search-section">
        <div class="CoveoSearchbox"></div>
      </div>
    </div>
    
  2. Create a QS model.

    Create QS Model Example

  3. Associate the QS model with the query pipeline which processes search requests originating from the search interface.

    Associate QS Model Example

If the search box is still providing no query suggestions, ensure that enough usage analytics data is available to feed your QS model.

Requesting Query Suggestions Only When the Search Box Is Non-Empty

Coveo JavaScript Search Framework 2.6459 (July 2019)

By default, trending Coveo ML query suggestions are requested and rendered whenever focus is on the search box input.

To change this behavior, set the querySuggestCharacterThreshold option of the Omnibox component to a value greater than 0.

The following configuration ensures that query suggestions only get rendered from the moment the end user starts entering a query in the search box.

<div class="CoveoSearchbox" data-query-suggest-character-threshold="1"></div>

Rendering Query Suggestion Result Previews

Pilot Feature in 2.7610 (December 2019)

In some search interfaces, particularly in the context of commerce, you may want to render previews of the most relevant results when focus is on a query suggestion.

QuerySuggestPreview Demo

To do so, your search interface must initialize a QuerySuggestPreview component*.

*The QuerySuggestPreview component is still a pilot feature, and it currently has some known issues:

  • Its default result template does not work in Firefox.

  • It is not compatible with field value suggestions.

  • It does not support accessibility features.

With the following configuration, when focus is on a query suggestion for 200 milliseconds1, the QuerySuggestPreview component requests the top three2 results matching the focused query, and renders those results using a simple default template3.

<!-- ... -->
<div class="CoveoQuerySuggestPreview"></div>
<div class="CoveoSearchbox"></div>
<!-- ... -->
</div>

1: See the executeQueryDelay option.

2: See the numberOfPreviewResults option.

3: See the Using Custom Query Suggest Preview Result Templates below.

Using Custom Query Suggest Preview Result Templates

To customize the way the QuerySuggestPreview component visually renders results:

  • (Option 1) Use the resultTemplate option to specify a previously registered template to apply to all results.

    <div class="CoveoQuerySuggestPreview"
         data-result-template-id="qsp-template"></div>
    <!-- ... -->
    <script id="qsp-template" class="result-template" type="text/html">
      <!-- ... -->
    </script>
    

OR

  • (Option 2) Embed a set of conditional templates inside the element bound to the QuerySuggestPreview component instance.

    This is essentially the same approach you would use to specify custom result templates for a ResultList component.

    If you use this approach, for each result to render, the first template whose condition is satisfied by the result will apply. Thus, the last embedded template should typically have no condition, and be considered the default template.

    <div class="CoveoQuerySuggestPreview">
      <script id="qsp-template-products" class="result-template" type="text/html"
              data-field-documenttype="Product">
        <!-- ... -->
      </script>
      <script id="qsp-template-services" class="result-template" type="text/html"
              data-field-documenttype="Service">
        <!-- ... --->
      </script>
      <script id="qsp-template-default" class="result-template" type="text/html">
        <!-- ... -->
      </script>
    </div>
    

For more information on result templates, see JavaScript Search Framework Result Templates.

Providing Facet Value Suggestions

Coveo JavaScript Search Framework 2.4094.8 (May 2018)

You can use the FacetValueSuggestions component to provide end users with scoped query suggestions based on the values of a specific facet-enabled field.

FacetValueSuggestions Example

Basic Usage

The following code sample provides a minimal working example of a FacetValueSuggestions component:

<!DOCTYPE html>
<html>
<head>
  <!-- The component requires JS Search Framework v2.4094.8 or above -->
  <link rel="stylesheet" href="https://static.cloud.coveo.com/searchui/v2.4094/css/CoveoFullSearch.css"/>
  <script class="coveo-script" src="https://static.cloud.coveo.com/searchui/v2.4094/js/CoveoJsSearch.Lazy.min.js"></script>
  <script>
    document.addEventListener("DOMContentLoaded", () => {
      Coveo.SearchEndpoint.configureSampleEndpointV2();
      Coveo.init(document.getElementById("search"));
    });
  </script>
</head>
<body id="search" class="CoveoSearchInterface">
  <div class="coveo-search-section">
    <!-- See note 1 below -->
    <div class="CoveoSearchbox">
      <!-- See note 2 below -->
      <div class="CoveoFacetValueSuggestions" data-field="@author"></div>
      <!-- See note 3 below -->
      <!-- <div class="CoveoFacetValueSuggestions"
                data-field="@author"
                data-use-query-suggestions="false"></div> -->
    </div>
  </div>
  <div class="coveo-main-section">
    <!-- See note 4 below -->
    <div class="coveo-facet-column">
      <div class="CoveoFacet" data-field="@author" data-title="Author"></div>
    </div>
    <div class="coveo-results-column">
      <div class="CoveoResultList"></div>
    </div>
  </div>
  <!-- See note 5 below -->
  <!-- <div class="CoveoHiddenQuery"></div> -->
</body>
</html>
  1. The FacetValueSuggestions component requires an Omnibox to work. By default, the Searchbox initializes an Omnibox.

  2. Minimally, you must set the field option of a FacetValueSuggestions component to the @-prefixed name of a field whose Facet option is enabled. You can initialize many FacetValueSuggestions components in the same search interface, as long as each instance references its own unique field.

  3. The FacetValueSuggestions component normally requires that the enableQuerySuggestAddon option be set to true on the Omnibox, which is the case by default. This implies that a Coveo ML QS model must be available in the target query pipeline. If this condition is not satisfied, set the useQuerySuggestions option of each FacetValueSuggestions component to false, otherwise the components will not work.

  4. While not mandatory, it is recommended to include a corresponding Facet for each FacetValueSuggestions component. This will allow end users to intuitively interact with the filters that apply when selecting a scoped query suggestion.

  5. If you cannot or do not want to use facets in your search interface, include a HiddenQuery component instead. Otherwise, selecting a scoped query suggestion provided by a FacetValueSuggestions component will not have the desired effect, as no additional filter will be applied.

Providing Scoped Query Suggestions Based on a Multi-Value Field

Coveo JavaScript Search Framework 2.5395.12 (January 2019)

You can use the isCategoryField and categoryFieldDelimitingCharacter options of a FacetValueSuggestions component to provide scoped query suggestions based on a field whose Multi-Value Facet option is enabled.

When you do so, it is recommended to include a corresponding CategoryFacet in your search interface.

In your Coveo Cloud organization, you have created a source called Living Things. In that source, each item describes a specific plant or animal. The @simpletaxonomy multi-value field gets populated by metadata representing the hierarchical categories to which each Living Things item belongs.

For instance, the field value is:

  • Animals; Animals > Mammals; for items describing dogs, cats, horses, etc.

  • Animals; Animals > Birds; for items describing parrots, eagles, crows, etc.

  • Plants; Plants > Trees; for items describing maples, oaks, firs, etc.

In your search interface, you configure a FacetValueSuggestions component (and a CategoryFacet) based on the @simpletaxonomy field:

<div id="search" class="CoveoSearchInterface">
  <div class="coveo-search-section">
    <div class="CoveoSearchbox">
      <div class="CoveoFacetValueSuggestions"
           data-field="@simpletaxonomy"
           data-is-category-field="true"
           data-category-field-delimiting-character=" > "></div>
      </div>
  </div>
  <div class="coveo-main-section">
    <div class="coveo-facet-column">
      <div class="CoveoCategoryFacet"
           data-field="@simpletaxonomy"
           data-title="Taxonomy"></div>
    </div>
    <div class="coveo-results-column">
      <div class="CoveoResultList"></div>
    </div>
  </div>
</div>

Your Omnibox can now provide scoped query suggestions similar to what is shown in the following animation:

Nice Friendly Parrot Example

You can use the templateHelper option of the FacetValueSuggestions component to specify a custom template to apply when rendering scoped query suggestions in the Omnibox.

You cannot set this option directly in the markup configuration of a FacetValueSuggestions component; you must rather set it in the init (or options) top-level function call (see Configuring Components).

When specified, the templateHelper option must be set to a function that returns a string or template literal, and receives the following arguments:

  1. A reference to the current IFacetValueSuggestionRow object.

  2. A reference to the Omnibox in which to render the scoped query suggestions.

Typically, the function should leverage some attributes of the first argument (e.g., keyword, value, etc.) to generate a template literal (which may contain HTML).

Consider the following markup:

<div id="search" class="CoveoSearchInterface">
  <div class="CoveoHiddenQuery"></div>
  <div class="coveo-search-section">
    <div class="CoveoSearchbox">
      <div id="authorFacetValueSuggestions" class="CoveoFacetValueSuggestions"
           data-field="@author"
           data-use-query-suggestions="false"></div>
      <div id="filetypeFacetValueSuggestions" class="CoveoFacetValueSuggestions"
           data-field="@filetype"
           data-use-query-suggestions="false"></div>
    </div>
  </div>
</div>

You could specify a generic custom template function to execute when rendering suggestions for each FacetValueSuggestions component:

Coveo.init(document.getElementById("search"), {
  FacetValueSuggestions: {
    templateHelper: (row, omnibox) => {
      return `<strong>${row.keyword}</strong> where <strong>${row.field}=="${row.value}"</strong> (~${row.numberOfResults} results)`;
    }
  }
});

FacetValueSuggestions Custom Template Example 1

You could also specify a specific custom template function for each component instance by targeting its HTML id attribute in the init (or options) top-level function call:

Coveo.init(document.getElementById("search"), {
  authorFacetValueSuggestions: {
    templateHelper: (row, omnibox) => {
      return `<strong>${row.keyword}</strong> in items authored by <em>${row.value}</em>`;
    }
  },
  filetypeFacetValueSuggestions: {
    templateHelper: (row, omnibox) => {
      const normalizedRowValues = {
        "gmailmessage": "Gmail message",
        "lithiummessage": "Lithium message",
        "pdf": "PDF"
      }
      const normalizedRowValue = normalizedRowValues[row.value] || row.value;
      return `<strong>${row.keyword}</strong> in ${normalizedRowValue}s`;
    }
  }
});

FacetValueSuggestions Custom Template Example 2

Providing Field Suggestions

Consider providing Coveo ML query suggestions rather than field suggestions, as the former yields better performance and relevance.

The FieldSuggestions component can provide Omnibox suggestions based on field values.

Field Suggestions Example

To enable basic field suggestions in a search interface:

  1. Ensure that the search interface initializes an Omnibox component.

  2. Initialize a FieldSuggestions component in your search page, and set its field option to the @-prefixed name of the field on which you want to base the suggestions.

<div id="search" class="CoveoSearchInterface">
  <div class="coveo-search-section"></div>
    <div class="CoveoSearchbox"></div>
    <div class="CoveoFieldSuggestions" data-field="@author"></div>
  </div>
</div>
  • You can add several FieldSuggestions components in a search interface to provide query completion suggestions based on different fields.

  • Ensure that the Facet option is enabled on each field you use to provide field suggestions (see Add or Edit a Field).

Recommended Articles