FindableChat
A complete AI chat widget with streaming responses, citations, and follow-up suggestions.
Live Chat Demo
Try: “What ventilation system is installed?”Try: “Tell me about fire safety measures”Try: “Show the electrical distribution”
Building Assistant
Full Example
<FindableChat
buildingId="bld-789"
placeholder="Ask about your building..."
title="Ask Findable"
language="en"
mode="balanced"
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} />}
/>Props
| Prop | Type | Default | Description |
|---|---|---|---|
buildingId* | string | — | The building to ask questions about. |
placeholder | string | 'Ask about your building...' | Input placeholder text. |
title | string | 'Ask Findable' | Header title. Set to an empty string to hide the header. |
language | 'en' | 'no' | 'nb' | 'nn' | — | Language for AI responses. |
mode | 'fast' | 'balanced' | 'deep' | — | How much work goes into each answer. 'fast' is roughly 15x cheaper and several times faster, with shallower synthesis across many documents. 'balanced' is the default engine when omitted. 'deep' is the most thorough and most expensive. |
reasoningEffort | 'low' | 'medium' | 'high' | 'medium' | Deprecated: use mode. 'high' behaves like 'deep'; 'low' and 'medium' both behave like 'balanced'. Ignored when mode is set. |
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 | — | Called when a new conversation thread starts. |
onCitationClick | (citation: AskCitation) => void | — | Called when a citation badge is clicked. |
renderMessage | (message: ChatMessage) => JSX.Element | — | Custom message renderer for full UI control. |
Headless Hook: useChat
For full control over the UI, use the useChat hook directly:
import { useChat } from '@findable-ai/react';
function CustomChat() {
const {
messages,
status,
followUpSuggestions,
threadId,
sendMessage,
cancelStream,
clearChat,
} = useChat({ buildingId: 'bld-789' });
return (
<div>
{messages.map((msg) => (
<div key={msg.id} className={msg.role}>
{msg.content}
{msg.isStreaming && <span>...</span>}
</div>
))}
<input
onKeyDown={(e) => {
if (e.key === 'Enter') {
sendMessage(e.currentTarget.value);
e.currentTarget.value = '';
}
}}
/>
{status === 'streaming' && (
<button onClick={cancelStream}>Stop</button>
)}
</div>
);
}useChat Return Value
| Prop | Type | Default | Description |
|---|---|---|---|
messages | ChatMessage[] | — | Conversation messages. |
status | ChatStatus | — | 'idle' | 'starting' | 'streaming' | 'finished' | 'failed'. |
followUpSuggestions | string[] | — | Suggested follow-up questions. |
threadId | string | null | — | Current conversation thread ID. |
sendMessage | (query: string, documentIds?: string[]) => void | — | Send a message. |
cancelStream | () => void | — | Cancel an in-flight stream. |
clearChat | () => void | — | Clear messages and start a new thread. |