> ## Documentation Index
> Fetch the complete documentation index at: https://algolia.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Chat

> Displays a chat interface to interact with a generative AI assistant built with Algolia Agent Studio.

export const customLabel_0 = "in beta"

<div className="not-prose algolia-flavor-switcher">
  <div className="afs-dropdown">
    <div className="afs-trigger" role="button" tabIndex="0" aria-haspopup="listbox">
      <span className="afs-current">React</span>

      <svg className="afs-chevron lucide lucide-chevron-down" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
        <path d="m6 9 6 6 6-6" />
      </svg>
    </div>

    <ul className="afs-menu" role="listbox">
      <li role="option" aria-selected="false"><a className="afs-option" href="/doc/api-reference/widgets/chat/js"><span className="afs-option-name">JavaScript</span><span className="afs-option-lib">InstantSearch.js</span></a></li>
      <li role="option" aria-selected="true"><a className="afs-option is-current" href="/doc/api-reference/widgets/chat/react"><span className="afs-option-name">React</span><span className="afs-option-lib">React InstantSearch</span></a></li>
    </ul>
  </div>
</div>

<Callout icon="flask-conical" color="#14b8a6">
  This widget is **{customLabel_0 || "experimental"}** and is subject to change in minor versions.
</Callout>

For more information, see [Agent Studio](/doc/guides/algolia-ai/agent-studio).

```tsx Signature theme={"system"}
<Chat
  // Required prop, either one of
  agentId={string}
  transport={object}
  // Optional props (agentId only)
  feedback={boolean}
  requestOptions={object}
  // Optional props
  getSearchPageURL={function}
  tools={object}
  context={object | function}
  initialMessages={array}
  initialUserMessage={string}
  resume={boolean}
  disableTriggerValidation={boolean}
  onFinish={function}
  classNames={object}
  translations={object}
  layoutComponent={function}
  // Optional component props
  itemComponent={function}
  headerCloseIconComponent={function}
  headerMaximizeIconComponent={function}
  headerMinimizeIconComponent={function}
  headerTitleIconComponent={function}
  messagesErrorComponent={function}
  loaderComponent={function}
  promptFooterComponent={function}
  promptHeaderComponent={function}
  suggestionsComponent={function}

  ...props={ComponentProps<'div'>}
/>
```

## Import

```jsx JavaScript icon=code theme={"system"}
import { Chat } from "react-instantsearch";
```

## About this widget

`<Chat>` is a widget to display a chat interface that interacts with a generative AI assistant.

See also: [Agent Studio](/doc/guides/algolia-ai/agent-studio)

<Note>
  `<Chat>` renders the chat panel but doesn't provide a way to open it. Add one entry point to the same `<InstantSearch>` instance: the [`<ChatTrigger>`](/doc/api-reference/widgets/chat-trigger/react) widget, [AI mode](/doc/guides/building-search-ui/going-further/chat-customization/ai-search-experience/react) on a `SearchBox` or autocomplete, or an [inline layout](#param-layout-component). Otherwise, the widget logs a development warning. To silence it, set [`disableTriggerValidation`](#param-disable-trigger-validation) to `true`.
</Note>

## Examples

```jsx JavaScript icon=code theme={"system"}
import React from "react";
import { liteClient as algoliasearch } from "algoliasearch/lite";
import { InstantSearch, Chat, ChatTrigger } from "react-instantsearch";

const searchClient = algoliasearch("YourApplicationID", "YourSearchOnlyAPIKey");

function App() {
  return (
    <InstantSearch indexName="instant_search" searchClient={searchClient}>
      <Chat agentId="8f7c4a2d-3b1e-4d5f-9a6c-e2b1f5d0c3e9" />
      <ChatTrigger />
    </InstantSearch>
  );
}
```

## Props

<ParamField body="agentId" type="string">
  The unique identifier of the agent to connect to. You can find the `agentId` in the [Agent Studio dashboard](https://dashboard.algolia.com/generativeAi/agent-studio/agents).

  ```jsx JavaScript icon=code theme={"system"}
  <Chat agentId="8f7c4a2d-3b1e-4d5f-9a6c-e2b1f5d0c3e9" />
  ```
</ParamField>

<ParamField body="feedback" type="boolean">
  Whether to enable feedback (thumbs up/down) on assistant messages. Only available when using `agentId`.

  ```jsx JavaScript icon=code theme={"system"}
  <Chat
    agentId="8f7c4a2d-3b1e-4d5f-9a6c-e2b1f5d0c3e9"
    feedback={true}
  />
  ```
</ParamField>

<ParamField body="requestOptions" type="object">
  Request options to send with the built-in Agent Studio completion requests.
  Use this option only with `agentId`.
  It isn't available with a custom `transport` or custom `chat` instance.

  The object accepts the following properties:

  * `queryParameters` (`Record<string, string | number | boolean>`). Query parameters to append to each completion request.
  * `headers` (`Record<string, string> | Headers`). Headers to send with each completion request.

  InstantSearch always keeps `compatibilityMode=ai-sdk-5`,
  even if you set `compatibilityMode` in `queryParameters`.
  Custom headers can't override the required Algolia identity headers (`x-algolia-application-id`, `x-algolia-api-key`) or the `x-algolia-agent` header that identifies InstantSearch.
  When users regenerate an assistant message,
  InstantSearch sends `cache=false` even if `requestOptions.queryParameters.cache` is `true`.

  ```jsx JavaScript icon=code theme={"system"}
  <Chat
    agentId="8f7c4a2d-3b1e-4d5f-9a6c-e2b1f5d0c3e9"
    requestOptions={{
      queryParameters: {
        cache: false,
      },
      headers: {
        'X-Algolia-Secure-User-Token': 'ALGOLIA_SECURE_USER_TOKEN',
      },
    }}
  />
  ```
</ParamField>

<ParamField body="transport" type="HttpChatTransportInitOptions">
  A custom transport object to handle the communication between the chat widget and the agent. The API endpoint must be compatible with [Vercel AI SDK 5](https://ai-sdk.dev/docs/ai-sdk-ui/transport#custom-transport-configuration).

  <CodeGroup>
    ```jsx JavaScript icon=code theme={"system"}
    <Chat transport={{
      api: 'https://chatapi.example.com/api/v1/chat',
      headers: {
        'X-Session-Id': '8f7c4a2d-3b1e-4d5f-9a6c-e2b1f5d0c3e9',
        'X-Api-Version': '2025-01-01',
      },
    }} />;
    ```

    ```ts HttpChatTransportInitOptions icon="file-type" theme={"system"}
    type HttpChatTransportInitOptions = {
      api?: string;
      credentials?: Resolvable<RequestCredentials>;
      headers?: Resolvable<Record<string, string> | Headers>;
      body?: Resolvable<object>;
      fetch?: FetchFunction;
      // ...
    };
    ```
  </CodeGroup>
</ParamField>

<ParamField body="getSearchPageURL" type="(nextUiState: object) => string">
  A function to return the URL of the main search page with the `nextUiState`. This is used to navigate to the main search page when the user clicks on "View all" in the search tool.

  ```jsx JavaScript icon=code theme={"system"}
  <Chat
    getSearchPageURL={(nextUiState) => {
      return `/search?${qs.stringify(nextUiState)}`;
    }}
  />
  ```
</ParamField>

<ParamField body="tools" type="Record<string, Tool>">
  An object defining the client-side tools that the agent can use to interact with your application. The object's keys are tool names that must match the tools defined in the [Agent Studio dashboard](/doc/guides/algolia-ai/agent-studio/how-to/dashboard#client-side-tools).

  The widget has a built-in renderer for the search tool. Import and use the exported constant as a key to customize the default rendering:

  * `SearchIndexToolType` (`'algolia_search_index'`). Displays search results from an Algolia index in a carousel.

  ```jsx JavaScript icon=code theme={"system"}
  import { SearchIndexToolType } from 'react-instantsearch';
  ```

  To customize only the appearance of each result in the built-in carousel, use the [`itemComponent`](#param-item-component) prop instead. To replace the whole carousel layout, override the `SearchIndexToolType` tool's `layoutComponent`. The tool result is on `message.output` (`hits`, `nbHits`, `queryID`):

  ```jsx JavaScript icon=code theme={"system"}
  <Chat
    agentId="YOUR_AGENT_ID"
    tools={{
      [SearchIndexToolType]: {
        layoutComponent: ({ message, sendEvent }) => {
          const items = message.output?.hits || [];

          return (
            <div className="MyCarousel">
              {items.map((item) => (
                <article className="MyCarousel-item" key={item.objectID}>
                  <img src={item.image} alt={item.name} />
                  <h3>{item.name}</h3>
                  <span>${item.price}</span>
                </article>
              ))}
            </div>
          );
        },
      },
    }}
  />
  ```

  For a step-by-step walkthrough, see [Customize the chat results carousel](/doc/guides/building-search-ui/going-further/chat-customization/results-carousel/react).

  Each tool is an object with the following properties:

  * `layoutComponent`. A React component that renders the tool call in the chat. Receives the following props:
    * `message`. The tool call message. It contains `input` (parameters from the agent) and `output` (the result you provide with `addToolResult`). For more information on the message structure, see the [Vercel AI SDK documentation](https://ai-sdk.dev/docs/reference/ai-sdk-ui/use-chat#messages.ui-message).
    * `indexUiState`. The current InstantSearch UI state.
    * `setIndexUiState`. Updates the InstantSearch UI state (for example, to refine filters or update the query based on the tool call).
    * `applyFilters`. Applies filters to the InstantSearch UI state from the tool call.
    * `addToolResult`. Sends the tool's output back to the agent. Call this at least once before the next message. For more information, see the [Vercel AI SDK documentation](https://ai-sdk.dev/docs/reference/ai-sdk-ui/use-chat#add-tool-result).
    * `onClose`. Dismisses the tool's UI in the chat.
    * `sendEvent`. Sends `click` or `conversion` events related to the tool call. For more information, see the [`insights`](/doc/api-reference/widgets/insights/react) middleware documentation.
  * `onToolCall`. Optional handler invoked when the agent calls the tool. Receives a parameter object with:
    * `input`. The parameters the agent passed to the tool.
    * `addToolResult`. Sends the tool's output back to the agent. For more information, see the [Vercel AI SDK documentation](https://ai-sdk.dev/docs/reference/ai-sdk-ui/use-chat#on-tool-call).
    * `toolCallId`. The unique identifier of the tool call.
    * `toolName`. The name of the tool being invoked.
    * `dynamic`. Whether the tool is dynamically registered.
  * `streamInput`. Optional boolean. When `true`, the default loader is suppressed as the tool's input is streamed from the agent.  Use the partial `input` in your `layout` template to render the streaming state as input chunks arrive.

  <CodeGroup>
    ```jsx JavaScript icon=code expandable theme={"system"}
    <Chat tools={{
      addToCart: {
        layoutComponent: ({ message, addToolResult }) => <div>
          <p>Add {message.input.objectID} to the cart?</p>
          <button onClick={async () => {
            // add the product to the cart
            await addProductToCart(message.input.objectID);
            // notify the agent that the tool has been used
            addToolResult({
              output: {
                text: `added ${message.input.objectID} to cart`,
                done: true,
              },
            });
          }}>Add to cart</button>
        </div>,
        onToolCall: ({ addToolResult }) => addToolResult({ output: {} }),
      },
      viewProduct: {
        layoutComponent: ({ message }) => {
          if (!message.output) {
            return <span>Loading product...</span>;
          }

          return <div>
            <h2>{message.output.productName}</h2>
            <p>{message.output.brand}</p>
            <img src={message.output.imageUrl} />
          </div>;
        },
        onToolCall: async ({ input, addToolResult }) => {
          addToolResult({
            // fetch product details from your index
            output: await fetchProductDetails(input.objectID),
          });
        },
      },

    }} />;

    ```

    ```ts Tool icon="file-type" expandable theme={"system"}
    type Tool = {
      layoutComponent: (props: ToolLayoutComponentProps) => JSX.Element;
      onToolCall?: (params: {
        input: unknown;
        addToolResult: (props: { output: unknown }) => Promise<void>;
        toolCallId: string;
        toolName: string;
        dynamic?: boolean;
      }) => void;
      streamInput?: boolean;
    };

    type ToolLayoutComponentProps = {
      message: { input: unknown; output: unknown };
      addToolResult: (props: { output: unknown }) => Promise<void>;
      applyFilters: (filters: object) => void;
      indexUiState: object;
      setIndexUiState: (state: object) => void;
      onClose: () => void;
      sendEvent: (eventType: 'click' | 'conversion', hit: Hit | Hit[], eventName: string) => void;
    };
    ```
  </CodeGroup>
</ParamField>

<ParamField body="context" type="Record<string, string> | () => Record<string, string>">
  Extra context to send with each user message (for example, the current page or selected locale).
  The widget sends this context with every message, but doesn't show it in the chat UI.

  `context` can be a static object or a function that returns an object at send time.
  The widget attaches it to the latest user message as `metadata.turnContext`, following the Agent Studio [per-turn context](/doc/guides/algolia-ai/agent-studio/how-to/turn-context) contract.
  The context never appears as a chat bubble.

  The context must be a flat object that maps strings to strings (up to 32 keys, 4,096 bytes total).
  Agent Studio validates the payload and rejects malformed contexts.
  For details, see [Per-turn context](/doc/guides/algolia-ai/agent-studio/how-to/turn-context).

  <Warning>
    The widget sends `context` to the agent in plain text. Don't put secrets, access tokens, or personally identifiable information you don't intend to share with the model in this field.
  </Warning>

  <CodeGroup>
    ```jsx Static object theme={"system"}
    <Chat
      agentId="YOUR_AGENT_ID"
      context={{ locale: "en", currentPage: "/products" }}
    />
    ```

    ```jsx Function theme={"system"}
    <Chat
      agentId="YOUR_AGENT_ID"
      context={() => ({
        locale: navigator.language,
        currentPage: window.location.pathname,
      })}
    />
    ```
  </CodeGroup>
</ParamField>

<ParamField body="initialMessages" type="UIMessage[]">
  Messages to pre-populate the chat with when it's initialized. These messages are added without triggering an AI response.

  `initialMessages` only applies when the chat has no existing messages. When `resume` is enabled, `initialMessages` is ignored.

  ```jsx JavaScript icon=code theme={"system"}
  <Chat
    agentId="YOUR_AGENT_ID"
    initialMessages={[
      {
        id: "welcome",
        role: "assistant",
        parts: [{ type: "text", text: "Hi! How can I help you today?" }],
      },
    ]}
  />
  ```
</ParamField>

<ParamField body="initialUserMessage" type="string">
  A message to send automatically when the chat is initialized.

  `initialUserMessage` is only sent when the chat has no existing messages. It's sent after `initialMessages` are applied. When `resume` is enabled, this message isn't sent.

  ```jsx JavaScript icon=code theme={"system"}
  <Chat
    agentId="YOUR_AGENT_ID"
    initialUserMessage="Show me a few popular products to get started."
  />
  ```
</ParamField>

<ParamField body="resume" type="boolean" default={false}>
  Whether to resume an ongoing chat generation stream when the widget mounts. Use this when restoring a chat session after a page reload to continue receiving an in-flight assistant response.

  ```jsx JavaScript icon=code theme={"system"}
  <Chat agentId="YOUR_AGENT_ID" resume />
  ```
</ParamField>

<ParamField body="disableTriggerValidation" type="boolean" default={false}>
  Whether to skip the validation that requires a way to open the chat. By default, `<Chat>` logs a development warning unless the chat has an entry point: a [`<ChatTrigger>`](/doc/api-reference/widgets/chat-trigger/react) widget, [AI mode](/doc/guides/building-search-ui/going-further/chat-customization/ai-search-experience/react) on a `SearchBox` or autocomplete, or an [inline layout](#param-layout-component). Set this to `true` when you open the chat programmatically and don't render any of those.

  ```jsx JavaScript icon=code theme={"system"}
  <Chat agentId="YOUR_AGENT_ID" disableTriggerValidation />
  ```
</ParamField>

<ParamField body="onFinish" type="(options: { message, messages, isAbort, isDisconnect, isError }) => void">
  A callback called when the assistant response has finished streaming, including when the stream is aborted, disconnected, or fails.

  The callback receives an object with:

  * `message`: the final assistant message.
  * `messages`: the full message list including the new message.
  * `isAbort`: `true` if the stream was stopped with `stop()`.
  * `isDisconnect`: `true` if the connection was lost.
  * `isError`: `true` if the stream finished with an error.

  ```jsx JavaScript icon=code theme={"system"}
  <Chat
    agentId="YOUR_AGENT_ID"
    onFinish={({ message, isAbort, isError }) => {
      if (isError) {
        console.error("Chat stream failed", message);
        return;
      }
      if (!isAbort) {
        analytics.track("chat_message_completed", { messageId: message.id });
      }
    }}
  />
  ```
</ParamField>

<ParamField body="emptyComponent" type="(props: ChatEmptyProps) => JSX.Element">
  A component to customize the welcome screen shown before the first message, when the chat has no messages yet. Use it to display a greeting and starter prompts that send a message when clicked. It receives:

  * `sendMessage`. Sends a message to the agent. Call it with `{ text }` to submit a starter prompt as the first message.
  * `status`. The current chat status.
  * `onClose`. Dismisses the chat.
  * `setInput`. Sets the value of the prompt input without sending it.

  ```jsx JavaScript icon=code theme={"system"}
  import { Chat } from "react-instantsearch";

  function WelcomeScreen({ sendMessage }) {
    const prompts = ["What are your best-selling shoes?", "Show me new arrivals"];

    return (
      <div className="ais-ChatGreeting">
        <h2>How can I help you today?</h2>
        <div className="ais-ChatPromptSuggestions">
          {prompts.map((prompt) => (
            <button key={prompt} onClick={() => sendMessage({ text: prompt })}>
              {prompt}
            </button>
          ))}
        </div>
      </div>
    );
  }

  <Chat agentId="YOUR_CHAT_AGENT_ID" emptyComponent={WelcomeScreen} />;
  ```

  To render the default greeting (heading, subheading, and an optional banner) inside your component, use the exported `ChatGreeting` component from `react-instantsearch`.

  For a step-by-step walkthrough, see [Show starter prompts on the chat welcome screen](/doc/guides/building-search-ui/going-further/chat-customization/welcome-screen/react).
</ParamField>

<ParamField body="layoutComponent" type="(props: ChatLayoutOwnProps) => JSX.Element">
  A component to customize the overall layout of the chat widget. Use `ChatInlineLayout` for an inline (non-overlay) layout, or `ChatOverlayLayout` for the default floating overlay.
  To display a custom welcome screen before the first message,
  see [Show starter prompts on the chat welcome screen](/doc/guides/building-search-ui/going-further/chat-customization/welcome-screen/react).

  ```jsx JavaScript icon=code theme={"system"}
  import { Chat, ChatInlineLayout } from "react-instantsearch";

  <Chat
    agentId="8f7c4a2d-3b1e-4d5f-9a6c-e2b1f5d0c3e9"
    layoutComponent={ChatInlineLayout}
  />
  ```
</ParamField>

<ParamField body="loaderComponent" type="(props) => JSX.Element">
  A component to customize the loader shown while waiting for an AI response. Import the built-in `ChatMessageLoader` component from `react-instantsearch` to render the default loader, or provide your own component.

  ```jsx JavaScript icon=code theme={"system"}
  import { Chat, ChatMessageLoader } from "react-instantsearch";

  <Chat
    agentId="8f7c4a2d-3b1e-4d5f-9a6c-e2b1f5d0c3e9"
    loaderComponent={(props) => (
      <ChatMessageLoader
        {...props}
        translations={{ loaderText: "Thinking..." }}
      />
    )}
  />
  ```

  To replace the loading state, see [Customize the chat loading message](/doc/guides/building-search-ui/going-further/chat-customization/loading-message/react).
</ParamField>

<ParamField body="components props" type="() => JSX.Element">
  Components to customize the rendering of the widget.

  * `itemComponent`. Custom component for each result. Receives an object containing a single record.
  * `headerCloseIconComponent`. Header: close icon component.
  * `headerMaximizeIconComponent`. Header: maximize icon component. Receives a prop containing `{ maximized: boolean }` for conditional rendering.
  * `headerMinimizeIconComponent`. Header: minimize icon component.
  * `headerTitleIconComponent`. Header: title icon component (defaults to sparkles).
  * `messagesErrorComponent`. Messages: custom error component. By default, the widget shows a generic message ("Sorry, we are not able to generate a response at the moment. Please contact support.") and a "Start a new conversation" button that clears the conversation. Guardrail violations are shown verbatim instead of the generic message. The component receives:
    * `errorMessage`. The raw error message from the API or transport layer.
    * `onNewConversation`. Callback that clears the conversation and starts a new one. Use it to render a "Start a new conversation" action for guardrail-style errors where retrying fails again.
  * `assistantMessageLeadingComponent`. Assistant message: custom leading component (e.g. avatar).
  * `assistantMessageFooterComponent`. Assistant message: custom footer component.
  * `userMessageLeadingComponent`. User message: custom leading component (e.g. avatar).
  * `userMessageFooterComponent`. User message: custom footer component.
  * `promptFooterComponent`. Prompt: custom footer component.
  * `promptHeaderComponent`. Prompt: custom header component.
  * `suggestionsComponent`. Custom component to render prompt suggestions. Receives a prop containing `{ suggestions: string[], onSuggestionClick: (str: string) => void }`.

  To customize the button that opens the chat, use the [`<ChatTrigger>`](/doc/api-reference/widgets/chat-trigger/react) widget's `toggleIconComponent` prop instead.

  To add a disclaimer or policy notice, see [Add a legal notice to the chat widget](/doc/guides/building-search-ui/going-further/chat-customization/legal-notice/react).

  ```jsx JavaScript icon=code theme={"system"}
  <Chat
    // ...
    headerTitleIconComponent={() => <span>✨</span>}
    headerMaximizeIconComponent={({ maximized }) => (
      <span>{maximized ? "🔽" : "🔼"}</span>
    )}
    promptFooterComponent={() => (
      <a href="https://example.com/privacy-policy">Privacy policy</a>
    )}
  />
  ```
</ParamField>

<ParamField body="classNames" type="Partial<ChatClassNames>">
  The [CSS classes you can override](/doc/guides/building-search-ui/widgets/customize-an-existing-widget/react#style-your-widgets) and pass to the widget's elements.
  It's useful to style widgets with class-based CSS frameworks like [Bootstrap](https://getbootstrap.com) or [Tailwind CSS](https://tailwindcss.com).

  * `root`. The root element of the widget.
  * `container`. The container element.
  * `header`. The header section of the widget.
    * `root`. The root element.
    * `clear`. The clear button.
    * `close`. The close button.
    * `maximize`. The maximize button.
    * `title`. The title element.
    * `titleIcon`. The title icon element.
  * `messages`. The messages section of the widget.
    * `root`. The root element.
    * `content`. The scrollable content.
    * `scroll`. The scroll container.
    * `scrollToBottom`. The scroll to bottom button.
    * `scrollToBottomHidden`. The hidden state of the scroll to bottom button.
  * `message`. The message in the messages section.
    * `root`. The root element.
    * `container`. The message container.
    * `leading`. The leading element (e.g., avatar).
    * `content`. The content element.
    * `message`. The message text element.
    * `actions`. The action buttons container.
    * `footer`. The footer element.
  * `prompt`. The prompt section of the widget.
    * `root`. The root element.
    * `actions`. The actions container.
    * `body`. The body element.
    * `footer`. The footer element.
    * `header`. The header element.
    * `submit`. The submit button.
    * `textarea`. The textarea element.

  ```jsx JavaScript icon=code theme={"system"}
  <Chat
    classNames={{
      root: "MyCustomChat",
      container: "MyCustomChatContainer MyCustomChatContainer--subclass",
      header: {
        root: "MyCustomChatHeader",
        title: ["MyCustomChatHeaderTitle", "MyCustomChatHeaderTitle--subclass"],
        // ...
      },
      // ...
    }}
  />
  ```
</ParamField>

<ParamField body="translations" type="Partial<ChatTranslations>">
  A dictionary of translations to customize the UI text and support internationalization.

  * `header`. The header section of the widget.
    * `clearLabel`. Accessible label for the clear button.
    * `closeLabel`. Accessible label for the close button.
    * `maximizeLabel`. Accessible label for the maximize button.
    * `minimizeLabel`. Accessible label for the minimize button.
    * `title`. Title to display.
  * `messages`. The messages section of the widget.
    * `copyToClipboardLabel`. Accessible label for the copy to clipboard action.
    * `feedbackThankYouText`. Text shown after feedback is submitted (default: `'Thanks for your feedback!'`).
    * `loaderText`. Text to display in the loader.
    * `regenerateLabel`. Accessible label for the regenerate action.
    * `scrollToBottomLabel`. Accessible label for the scroll to bottom button.
    * `sendingFeedbackLabel`. Accessible label for the feedback spinner (default: `'Sending feedback...'`).
    * `thumbsDownLabel`. Accessible label for the thumbs down button (default: `'Dislike'`).
    * `thumbsUpLabel`. Accessible label for the thumbs up button (default: `'Like'`).
  * `message`. Individual message in the messages section.
    * `messageLabel`. Accessible label for the message.
    * `actionsLabel`. Accessible label for the actions container.
  * `prompt`. The prompt section of the widget.
    * `disclaimer`. Disclaimer text shown in the prompt footer.
    * `emptyMessageTooltip`. Tooltip for the submit button when message is empty.
    * `sendMessageTooltip`. Tooltip for the send button.
    * `stopResponseTooltip`. Tooltip for the stop button.
    * `textareaLabel`. Accessible label for the textarea.
    * `textareaPlaceholder`. Placeholder text for the textarea.

  To add richer prompt or message notices, see [Add a legal notice to the chat widget](/doc/guides/building-search-ui/going-further/chat-customization/legal-notice/react).

  ```jsx JavaScript icon=code theme={"system"}
  <Chat
    translations={{
      header: {
        title: "My AI shopping assistant",
        closeLabel: "Close chat",
        // ...
      },
      // ...
    }}
  />
  ```
</ParamField>

<ParamField body="...props" type="React.ComponentProps<'div'>">
  Any `<div>` prop to forward to the root element of the widget.

  ```jsx JavaScript icon=code theme={"system"}
  <Chat className="MyCustomChat" title="My custom title" />
  ```
</ParamField>

## Streaming and resumption

Assistant responses stream over [Server-Sent Events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events).
The `useChat` hook exposes the streaming lifecycle if you want to drive a custom UI.

### Status values

`useChat` returns a `status` value, which can be one of:

* `'ready'`. The chat is idle and ready to accept a new message.
* `'submitted'`. A user message was submitted and the assistant hasn't started responding yet.
* `'streaming'`. The assistant is streaming a response.
* `'error'`. The last response finished with an error. Call `clearError()` before sending a new message.

Each message part also carries a `state` of `'streaming'` or `'done'` while the response streams.

### Stop and resume

`useChat` also returns:

* `stop()`. Aborts the current streaming response. The `onFinish` callback runs with `isAbort: true`.
* `resumeStream()`. Reconnects to an in-flight stream. Call this on mount, or pass [`resume`](#param-resume) to `<Chat>` to do it automatically.

```jsx JavaScript icon=code theme={"system"}
import { useChat } from "react-instantsearch";

function StopButton() {
  const { status, stop } = useChat({ agentId: "YOUR_AGENT_ID" });

  if (status !== "streaming") {
    return null;
  }

  return <button onClick={() => stop()}>Stop</button>;
}
```

To resume an ongoing stream after a reload, set [`resume`](#param-resume) on `<Chat>`, or call `resumeStream()` from a custom component.
