CxJS

getSearchQueryHighlighter

import { getSearchQueryHighlighter } from 'cx/util'; Copied

The getSearchQueryHighlighter function creates a function that splits text into chunks for highlighting matched search terms.

Basic Usage

import { getSearchQueryHighlighter } from "cx/util";

const highlighter = getSearchQueryHighlighter("john");
const chunks = highlighter("John Doe");
// Result: ["", "John", " Doe"]

The result is an array where odd indices (1, 3, 5…) contain matched text that should be highlighted.

How It Works

The function splits the query into terms and creates a highlighter that segments text based on matches.

import { getSearchQueryHighlighter } from "cx/util";

// Single term
const highlight = getSearchQueryHighlighter("react");
highlight("React Components");
// ["", "React", " Components"]

// Multiple terms
const multiHighlight = getSearchQueryHighlighter("react hook");
multiHighlight("React Custom Hook");
// ["", "React", " Custom ", "Hook", ""]

// Empty query returns text unchanged
const noHighlight = getSearchQueryHighlighter("");
noHighlight("Any text");
// ["Any text"]

Rendering Highlighted Text

import { getSearchQueryHighlighter } from "cx/util";

function HighlightedText({ text, query }: { text: string; query: string }) {
  const highlighter = getSearchQueryHighlighter(query);
  const chunks = highlighter(text);

  return (
    <span>
      {chunks.map((chunk, i) =>
        i % 2 === 1 ? (
          <mark key={i}>{chunk}</mark>
        ) : (
          <span key={i}>{chunk}</span>
        )
      )}
    </span>
  );
}

// Usage
<HighlightedText text="John Doe Smith" query="john smith" />
// Renders: <mark>John</mark> Doe <mark>Smith</mark>

Caching

The highlighter supports caching to avoid recreating the function for repeated queries.

import { getSearchQueryHighlighter } from "cx/util";

// Enable caching with default 5-second duration
const highlighter = getSearchQueryHighlighter("search term", { cache: true });

// Custom cache duration (10 seconds)
const cachedHighlighter = getSearchQueryHighlighter("search term", {
  cache: true,
  cachePeriod: 10000,
});

With Search Results

import { getSearchQueryPredicate, getSearchQueryHighlighter } from "cx/util";

interface SearchResult {
  id: string;
  title: string;
  description: string;
}

function SearchResults({
  items,
  query,
}: {
  items: SearchResult[];
  query: string;
}) {
  const predicate = getSearchQueryPredicate(query);
  const highlighter = getSearchQueryHighlighter(query, { cache: true });

  const filtered = items.filter(
    (item) => predicate(item.title) || predicate(item.description)
  );

  return (
    <ul>
      {filtered.map((item) => (
        <li key={item.id}>
          <h3>{renderHighlighted(highlighter(item.title))}</h3>
          <p>{renderHighlighted(highlighter(item.description))}</p>
        </li>
      ))}
    </ul>
  );
}

function renderHighlighted(chunks: string[]) {
  return chunks.map((chunk, i) =>
    i % 2 === 1 ? <mark key={i}>{chunk}</mark> : chunk
  );
}

API

function getSearchQueryHighlighter(
  query: string,
  options?: {
    cache?: boolean;
    cachePeriod?: number;
  }
): (text: string) => string[];
ParameterTypeDescription
querystringThe search query string
options.cachebooleanEnable caching of the highlighter function
options.cachePeriodnumberCache duration in milliseconds (default: 5000)

Returns: A function that splits text into alternating non-match/match chunks.

See Also