@findable-ai/react
v0.2.4
Published
React components and hooks for the Findable Partner API
Readme
@findable-ai/react
Drop-in React components and headless hooks for the Findable Partner API. Five lines to a working AI chat in your app.
Full documentation: docs.findable.dev
Installation
npm install @findable-ai/reactQuick start
import { FindableProvider, FindableChat } from '@findable-ai/react';
import '@findable-ai/react/styles.css';
function App() {
return (
<FindableProvider apiKey="YOUR_API_KEY" buildingOwnerId="YOUR_BUILDING_OWNER_ID">
<FindableChat buildingId="bld-789" />
</FindableProvider>
);
}That's it — a fully working chat widget with streaming responses, citations, and follow-up suggestions.
Components
<FindableChat>
Full-featured chat widget with message history, streaming, citations, and follow-up suggestions.
<FindableChat
buildingId="bld-789"
placeholder="Ask about your building..."
title="Ask Findable"
language="en"
reasoningEffort="medium"
showCitations={true}
showFollowUps={true}
className="my-chat"
onError={(err) => console.error(err)}
onThreadCreated={(threadId) => saveThreadId(threadId)}
onCitationClick={(citation) => openDocument(citation.documentId)}
renderMessage={(msg) => <CustomMessage {...msg} />}
/>| Prop | Type | Default | Description |
| ----------------- | --------------------------------------- | ------------------------------ | ------------------------------------ |
| buildingId | string | required | Building to query |
| placeholder | string | "Ask about your building..." | Input placeholder |
| title | string | "Ask Findable" | Header title (empty string hides it) |
| language | 'en' \| 'no' \| 'nb' \| 'nn' | — | Response language |
| reasoningEffort | 'low' \| 'medium' \| 'high' | — | AI reasoning effort |
| showCitations | boolean | true | Show inline citation badges |
| showFollowUps | boolean | true | Show follow-up suggestion chips |
| className | string | — | Additional CSS class |
| onError | (error: Error) => void | — | Error callback |
| onThreadCreated | (threadId: string) => void | — | New thread callback |
| onCitationClick | (citation: AskCitation) => void | — | Citation click handler |
| renderMessage | (message: ChatMessage) => JSX.Element | — | Custom message renderer |
<FindableSearch>
Document search with debounced input, results list, and pagination.
<FindableSearch
buildingId="bld-789"
placeholder="Search documents..."
maxResults={10}
debounceMs={300}
className="my-search"
onHitClick={(hit) => window.open(`/docs/${hit.id}`)}
renderHit={(hit) => <CustomHit {...hit} />}
/>| Prop | Type | Default | Description |
| ------------- | --------------------------------- | ----------------------- | --------------------------------- |
| buildingId | string | — | Building to search (omit for all) |
| placeholder | string | "Search documents..." | Input placeholder |
| maxResults | number | 10 | Results per page |
| debounceMs | number | 300 | Input debounce delay |
| className | string | — | Additional CSS class |
| onHitClick | (hit: SearchHit) => void | — | Result click handler |
| onError | (error: Error) => void | — | Error callback |
| renderHit | (hit: SearchHit) => JSX.Element | — | Custom result renderer |
Headless hooks
For complete control over the UI, use the hooks directly:
useChat
import { useChat } from '@findable-ai/react';
function MyChat() {
const { messages, status, followUpSuggestions, sendMessage, cancelStream, clearChat, threadId } =
useChat({ buildingId: 'bld-789' });
return (
<div>
{messages.map((msg) => (
<div key={msg.id} className={msg.role}>
{msg.content}
</div>
))}
<button onClick={() => sendMessage('What are the fire safety docs?')}>Ask</button>
</div>
);
}useSearch
import { useSearch } from '@findable-ai/react';
function MySearch() {
const { results, totalHits, isLoading, error, search, loadMore, clear } =
useSearch({ buildingId: 'bld-789' });
return (
<div>
<input onChange={(e) => search(e.target.value)} />
{results.map((hit) => (
<div key={hit.id}>{hit.filename}</div>
))}
{results.length < totalHits && <button onClick={loadMore}>Load more</button>}
</div>
);
}Theming
Import the default styles and override CSS custom properties:
@import '@findable-ai/react/styles.css';
.findable-root {
--findable-color-primary: #e63946;
--findable-color-bg: #ffffff;
--findable-color-text: #1a1a1a;
--findable-font-family: 'Inter', sans-serif;
--findable-radius-md: 12px;
--findable-chat-height: 500px;
}See the full list of CSS custom properties in the theming guide.
SDK access
The underlying FindableClient is available for direct API calls:
import { useFindableClient } from '@findable-ai/react';
function MyComponent() {
const client = useFindableClient();
// Use client.ask(), client.search(), client.listBuildings(), etc.
}Documentation
Licence
MIT
