Implement highlighting
Implement highlighting
This is for:
DeveloperTo improve the user experience, you may want to implement text highlighting. Coveo Headless offers highlighting for the following search elements:
-
-
title
-
excerpt
-
printable URI
-
first sentences
-
summary
-
This article explains how to implement highlighting in your Headless search interface.
Highlight Query Suggestions
Let’s assume that you have a SearchBox
component which offers clickable suggestions.
Each time you add or delete a character in the search field, Headless performs a querySuggest
request to the Search API.
The response includes highlights and may look like this:
{
"completions" :
[
{
"expression" : "pdf",
"score" : 1019.0259590148926,
"highlighted" : "{pdf}",
"executableConfidence" : 1.0,
"objectId" : "20c05008-3afc-5f4e-9695-3ec326a5f745"
}, {
"expression" : "filetype pdf",
"score" : 19.025959014892578,
"highlighted" : "[filetype] {pdf}",
"executableConfidence" : 1.0,
"objectId" : "39089349-6e45-5c18-991c-7158143ec468"
}
],
"responseId" : "9373a3c0-2c5c-4c9d-8adf-8bffd253ae3d"
}
To highlight query suggestions, update the target SearchBox
controller instance as shown in the following code:
import {SearchBox as HeadlessSearchBox, buildSearchBox} from '@coveo/headless';
import {headlessEngine} from '../engine';
import {FunctionComponent, useEffect, useState} from 'react';
export const searchBox = buildSearchBox(headlessEngine, {
options: {
highlightOptions: {
notMatchDelimiters: {
open: '<strong>',
close: '</strong>',
},
correctionDelimiters: {
open: '<i>',
close: '</i>',
},
},
},
});
interface SearchBoxProps {
controller: HeadlessSearchBox;
}
const suggestionStyle = {
cursor: 'pointer',
};
export const SearchBox: FunctionComponent<SearchBoxProps> = (props) => {
const {controller} = props;
const [state, setState] = useState(controller.state);
useEffect(() => controller.subscribe(() => setState(controller.state)), [
controller,
]);
return (
<div className="search-box">
<input
value={state.value}
onChange={(e) => controller.updateText(e.target.value)}
onKeyDown={(e) => e.key === 'Enter' && controller.submit()}
/>
{state.suggestions.length > 0 && (
<ul>
{state.suggestions.map((suggestion) => {
return (
<li
style={suggestionStyle}
key={suggestion.rawValue}
onClick={() => controller.selectSuggestion(suggestion.rawValue)}
dangerouslySetInnerHTML={{__html: suggestion.highlightedValue}}
></li>
);
})}
</ul>
)}
</div>
);
};
Adds the highlighting delimeters during initialization of a SearchBox controller instance (see SuggestionHighlightingOptions ).
If you use valid HTML tags as shown in this example, Headless interprets them as tags rather than as regular text. |
|
Adds a condition on showing a bulleted list of suggestions (if any). | |
Applies highlighting to the suggestions. The highlighting depends on responses from the Search API. |
Highlight Result Elements
Highlighting result elements operates a bit differently, but it employs the same approach as with the SearchBox
component.
You can specify what and how you want to highlight using the highlightString
method.
For example, you can highlight the excerpts in your result list as shown below.
import {
Result,
ResultList as HeadlessResultList,
buildResultList,
HighlightUtils,
} from '@coveo/headless';
import {headlessEngine} from '../engine';
import {FunctionComponent, useEffect, useState} from 'react';
export const resultList = buildResultList(headlessEngine);
interface ResultListProps {
controller: HeadlessResultList;
}
export const ResultList: FunctionComponent<ResultListProps> = (props) => {
const {controller} = props;
const [state, setState] = useState(controller.state);
useEffect(() => controller.subscribe(() => setState(controller.state)), [
controller,
]);
if (!state.results.length) {
return <div>No results</div>;
}
const highlightExcerpt = (result: Result) => {
return HighlightUtils.highlightString({
content: result.excerpt,
highlights: result.excerptHighlights,
openingDelimiter: '<strong>',
closingDelimiter: '</strong>',
});
};
return (
<div className="result-list">
<ul>
{state.results.map((result) => (
<li key={result.uniqueId}>
<article>
<h2>{result.title}</h2>
<p
dangerouslySetInnerHTML={{
__html: highlightExcerpt(result),
}}
></p>
</article>
</li>
))}
</ul>
</div>
);
};
Imports the HighlightUtils module so you can use the highlightString method in your component. |
|
Creates a custom function that returns the value of the highlightString method, which requires the following arguments:
|
|
Inserts an excerpt with highlighted strings right after the title. |