Skip to content

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

Ask a question to get started

Basic Usage

<FindableChat buildingId="bld-789" />

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

PropTypeDefaultDescription
buildingId*string—The building to ask questions about.
placeholderstring'Ask about your building...'Input placeholder text.
titlestring'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.
showCitationsbooleantrueShow inline citation badges.
showFollowUpsbooleantrueShow follow-up suggestion chips.
classNamestring—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

PropTypeDefaultDescription
messagesChatMessage[]—Conversation messages.
statusChatStatus—'idle' | 'starting' | 'streaming' | 'finished' | 'failed'.
followUpSuggestionsstring[]—Suggested follow-up questions.
threadIdstring | 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.