Skip to content

FindableSearch

A document search widget with debounced input, results list, and pagination.

Live Search Demo

Try searching for “fire”, “HVAC”, or “electrical”

Basic Usage

<FindableSearch buildingId="bld-789" />

Omit buildingId to search across all buildings:

<FindableSearch />

Props

PropTypeDefaultDescription
buildingIdstring—Scope results to a building. Omit to search all buildings.
placeholderstring'Search documents...'Input placeholder text.
maxResultsnumber10Results per page.
debounceMsnumber300Debounce delay in milliseconds.
classNamestring—Additional CSS class.
onHitClick(hit: SearchHit) => void—Called when a result row is clicked.
renderHit(hit: SearchHit) => JSX.Element—Custom hit renderer for full UI control.

Handling Clicks

<FindableSearch
  buildingId="bld-789"
  onHitClick={(hit) => {
    window.open(`/documents/${hit.id}`);
  }}
/>

Headless Hook: useSearch

import { useSearch } from '@findable-ai/react';

function CustomSearch() {
  const { results, totalHits, isLoading, query, search, loadMore, clear } =
    useSearch({ buildingId: 'bld-789', maxResults: 20 });

  return (
    <div>
      <input
        value={query}
        onChange={(e) => search(e.target.value)}
        placeholder="Search..."
      />
      {isLoading && <span>Loading...</span>}
      <ul>
        {results.map((hit) => (
          <li key={hit.id}>{hit.title || hit.filename}</li>
        ))}
      </ul>
      {results.length < totalHits && (
        <button onClick={loadMore}>Load more</button>
      )}
    </div>
  );
}

useSearch Return Value

PropTypeDefaultDescription
resultsSearchHit[]—Current search results.
totalHitsnumber—Total matching documents.
isLoadingboolean—Whether a search is in progress.
errorError | null—The latest search error, if any.
querystring—Current search query.
search(query: string) => void—Trigger a debounced search.
loadMore() => void—Load the next page of results.
clear() => void—Clear the query and results.