Ilana Docs
React

useQuery

useQuery manages multi-turn conversations. It automatically tracks the conversationId across queries so each subsequent call continues the same conversation.

Usage

import { useQuery } from '@ilana/react';

function Chat() {
  const { query, data, isLoading, error, reset } = useQuery();

  const handleAsk = async () => {
    await query('What pricing plans are available?');
  };

  return (
    <div>
      <button onClick={handleAsk} disabled={isLoading}>
        Ask
      </button>
      {isLoading && <p>Thinking...</p>}
      {data && <p>{data.response}</p>}
      {error && <p>Error: {error.message}</p>}
    </div>
  );
}

Options

const result = useQuery(options?: UseQueryOptions);
PropertyTypeDescription
onSuccess(data: QueryOutput) => voidCalled after a successful query
onError(error: IlanaError) => voidCalled when a query fails

Return Value: UseQueryResult

PropertyTypeDescription
query(input: string) => Promise<QueryOutput | null>Send a message
isLoadingbooleanWhether a query is in progress
dataQueryOutput | nullLast successful response
errorIlanaError | nullLast error
reset() => voidClear state and start a new conversation

Conversation Tracking

useQuery stores the conversationId internally. The first call starts a new conversation, and all subsequent calls continue it:

function Chat() {
  const { query, data } = useQuery();

  // First call — starts a new conversation
  await query('What plans do you offer?');

  // Second call — continues the same conversation
  await query('Tell me more about the Growth plan');

  // data.conversationId is the same for both
}

Call reset() to clear the state and start a new conversation.

Callbacks

const { query } = useQuery({
  onSuccess: (data) => {
    console.log('Response:', data.response);
    console.log('Intent:', data.intentDetected);
  },
  onError: (error) => {
    if (error.code === 'RATE_LIMITED') {
      showToast('Too many requests. Please wait.');
    }
  },
});