Customizing the Search UI in Our PDF Viewer Toolbar

The Nutrient interface offers full-text search for your PDFs. It lists the number of results for a given term, lets you walk through the results, and highlights all occurrences of the search term in the document. You could say that it pretty much behaves like your browser’s search feature.

Try for free Launch demo

Search field

But what if you wanted it to behave differently?

Nutrient lets you hook into search queries by listening to the search.termChange event. It will get triggered on every text change of the search field:

let lastSearchTerm = "";

instance.addEventListener("search.termChange", async event => {
  // Opt out from the default implementation.
  event.preventDefault();

  const { term } = event;
  // Update the search term in the search box. Without this line,
  // the search box would stay empty.
  instance.setSearchState(state => state.set("term", term));
  lastSearchTerm = term;

  // Perform a custom search for the term.
  const results = await customSearch(term, instance);

  // Our results could return in a different order than expected.
  // Let's make sure only results matching our current term are applied.
  if (term !== lastSearchTerm) {
    return;
  }

  // Finally, we apply the results. Note that you can also modify
  // the search state first and then pass the new state
  // to `instance.setSearchState`.
  const newState = instance.searchState.set("results", results);
  instance.setSearchState(newState);
});

To provide your own search implementation, you’d have to create a customSearch function — the only thing to keep in mind here is that you need to provide the result to the PSPDFKit.SearchState in the correct format, regardless of if the function is a little local implementation or a request to a huge search data center.

The following example shows how to search whole words in your document. By default, the search lists all matching text fragments of a document, regardless of if they’re whole words or not.

The customSearch function uses Nutrient’s instance.search under the hood, which is why you need to pass instance as an argument as well.

After the regular search, you can filter search results to only contain whole words:

async function customSearch(term, instance) {
  // You would get an error if you called `instance.search` with a term of
  // two characters or less.
  if (term.length <= 2) {
    return PSPDFKit.Immutable.List([]);
  }

  // Take the results from the default search as the foundation.
  const results = await instance.search(term);

  // You only want to find whole words that match the term you entered.
  const filteredResults = results.filter(result => {
    const searchWord = new RegExp(`\\b${term}\\b`, "i");
    return searchWord.test(result.previewText);
  });

  return filteredResults;
}

Your results should be a PSPDFKit.Immutable.List of PSPDFKit.SearchResults.

Additional information

To learn more about this topic, check out these API documentation pages:

Customizing the search UI

Nutrient Web SDKI allows you to customize every aspect of the search tool. This includes a number of supported public CSS classes that you can use to apply custom styling to. The up-to-date list of customizable elements can be found in the CSS section of our API reference.