Skip to main content
This widget is and is subject to change in minor versions.
For more information, see Agent Studio.
Signature

Import

About this widget

Use the chat widget to display a chat interface that interacts with a generative AI assistant. See also: Agent Studio
The chat widget renders the chat panel but doesn’t provide a way to open it. Add one entry point to the same InstantSearch instance: the chatTrigger widget, AI mode on a searchBox or autocomplete, or an inline layout. Otherwise, the widget logs a development warning. To silence it, set disableTriggerValidation to true.

Examples

JavaScript

Options

string | HTMLElement
required
The CSS Selector or HTMLElement to insert the widget into.
string
The unique identifier of the agent to connect to. You can find the agentId in the Agent Studio dashboard.
JavaScript
boolean
Whether to enable feedback (thumbs up/down) on assistant messages. Only available when using agentId.
JavaScript
object
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.
JavaScript
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.
JavaScript
function
A function to return the URL of the main search page with the nextUiState. This is used to go to the main search page when the user clicks on “View all” in the search tool.
JavaScript
object
An object that defines the client-side tools the agent can use to interact with your app. The object keys must match the tool names you defined in the Agent Studio dashboard.The widget has built-in renderers for search and Display Results tools. Import and use the exported constants as keys to customize the default rendering:
  • SearchIndexToolType ('algolia_search_index'). Displays search results from an Algolia index in a carousel.
  • DisplayResultsToolType ('algolia_display_results'). Displays grouped results from the tool’s streaming input in carousels.
JavaScript
To customize only the appearance of each result in the built-in carousel, use the item template instead. To replace the whole carousel layout, override the SearchIndexToolType tool’s layout template. The tool result is on context.message.output (hits, nbHits, queryID):
JavaScript
For a step-by-step walkthrough, see Customize the chat results carousel.Each tool is an object with the following properties:
  • templates. An object containing template functions for the tool.
    • layout. A tagged template function for rendering the tool call in the chat. It receives a single context object holding the tool’s own data alongside the shared chat state:
      • context.message. The tool call message. It contains input (parameters from the agent) and output (the result you provide with addToolResult). For more information about the message structure, see the Vercel AI SDK documentation.
      • context.records. The records the chat’s tools have fetched during the conversation, keyed by objectID. A tool that receives only object IDs reads the full record with context.records.get(objectID) rather than searching for it again. It also provides has(objectID) and getAll().
      • context.indexUiState. The current InstantSearch UI state.
      • context.setIndexUiState. Updates the InstantSearch UI state (for example, to refine filters or update the query based on the tool call).
      • context.applyFilters. Applies filters to the InstantSearch UI state from the tool call.
      • context.addToolResult. Sends the tool’s output back to the agent. You must call this at least once before the next message. For more information, see the Vercel AI SDK documentation.
      • context.onClose. Dismisses the tool’s UI in the chat.
      • context.sendEvent. Sends click or conversion events related to the tool call. For more information, see the insights middleware documentation.
      • context also carries the shared chat state available to the actions, empty, loader, and messages.error templates, such as messages, status, and stop.
      The root-level properties, such as message and addToolResult, are deprecated. The widget also passes them alongside context so templates written for earlier API versions keep working. Read these properties from context instead.
  • cancelOutput. Optional function that returns the output to report when the chat starts a new message while the tool call is waiting for a result. For example, a confirmation prompt can return { confirmed: false }. The function receives { toolCallId, input }. If you don’t provide it, the chat reports the tool call as failed. This only changes the output reported to the agent. The tool continues waiting locally, so you can still submit a result later.
  • 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.
    • 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.
  • shouldRender. Optional function that decides whether this tool call renders at all. It receives the chat context, plus message (the tool call under consideration) and parentMessage (the chat message it belongs to). Returning false skips the tool call and keeps the loader visible, so a tool can step aside for another one that renders in the same turn. When you omit it, the tool always renders. Overriding a built-in tool’s templates.layout keeps that tool’s own shouldRender unless you pass your own.
JavaScript
object | function
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 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.
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.
array
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 doesn’t have any existing messages. When resume is enabled, initialMessages is ignored.
JavaScript
string
A message to send automatically when the chat is initialized.initialUserMessage is only sent when the chat doesn’t have any existing messages. It’s sent after initialMessages are applied. When resume is enabled, this message isn’t sent.
JavaScript
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.
JavaScript
boolean | object
default:true
Whether to persist and restore the conversation and the open state of the chat panel from sessionStorage. When true (the default), the widget saves both the messages and whether the panel is open, and restores them when the widget re-initializes (for example, after a page reload). Set it to false to keep everything in memory only, so it’s cleared when the page reloads.To control each policy separately, pass an object with the messages and open booleans. Only what you set to true is persisted:
  • Omitted or true: persists the messages and the open state.
  • false or {}: persists nothing.
  • { messages: true }: persists the messages, but always starts with the panel closed.
  • { open: true }: persists the open state, but doesn’t persist messages.
With a custom chat instance, the instance owns message persistence, so only the open option is available. The open state is persisted by default: pass { open: false } to opt out.
boolean
default:false
Whether to skip the validation that requires a way to open the chat. By default, the chat widget logs a development warning unless the chat has an entry point: a chatTrigger widget, AI mode on a searchBox or autocomplete, or an inline layout. Set this to true when you open the chat programmatically and don’t render any of those.
JavaScript
function
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.
JavaScript
function
A function that decides whether to resubmit the conversation to the agent without user input. It receives an object with messages, the current message list, and returns a boolean or a promise that resolves to one. When it returns true, the widget sends the conversation again so the agent can continue its turn.By default, the widget uses lastAssistantMessageIsCompleteWithToolCalls. It returns true when the last step of the last assistant message has at least one client-side tool call, and every one of those calls has an output or an error. This is what lets the agent act on the results of your tools and keep answering. The function ignores tool calls the agent executes on its own side, because their results don’t come from your app.The widget evaluates the function only for a response with at least one required client-side tool call. It waits for the response to finish streaming and for every required client-side tool call in that response to have a result, whichever comes last. It evaluates each response at most once, and skips a stream that’s stopped or fails.Return false to stop the widget from continuing turns on its own, for example when your tools end the turn and users send the next message.With a custom chat instance, set sendAutomaticallyWhen on the instance instead.
Whether the widget makes InstantSearch require a main search request. By default (true), the widget contributes to the main search. Set it to false to opt the widget out of the main search: if it’s the only widget on the page, no main search request is sent.
JavaScript
boolean
default:false
Whether to display reasoning parts from assistant messages. Each reasoning part appears in a collapsed disclosure in its original message order. Users can expand or collapse each part, and the active part indicates that reasoning is still in progress.Copied assistant messages include the answer text, not the reasoning.
JavaScript
string
default:"messages-end"
Where the loader appears while a chat turn is in progress.
  • messages-end. Renders the loader in its own row after the last message.
  • message-inline. Renders the loader inside the streaming assistant message, after the content received so far. Before the first assistant part arrives, the loader appears in its own row.
JavaScript
To place the loader elsewhere in the chat panel, use CSS. See Control when and where the chat loader shows.
function
Controls when the loader appears. The function receives the loader context and defaultValue, which indicates whether the widget would show the loader by default. The timing options still apply to the returned value.Relevant context properties include:
  • status. The current chat status: 'ready', 'submitted', 'streaming', or 'error'.
  • phase. The current phase of the turn: 'submitted', 'tool', 'reasoning', or 'thinking'.
  • message. The assistant message associated with the loader, when available.
  • messages. The full conversation.
  • tools. The tools available to the agent.
  • defaultValue. Whether the widget would show the loader by default.
JavaScript
number
default:250
The delay, in milliseconds, before the loader reappears after being hidden earlier in the same turn. The first loader in a turn isn’t delayed. Set this option to 0 to show the loader immediately after loading starts.
JavaScript
number
default:200
The minimum time, in milliseconds, that the loader remains visible while the turn is running. This prevents the loader from briefly appearing and disappearing. The loader hides immediately after the turn ends.
JavaScript
object
The templates to use for the widget.
JavaScript
object
The CSS classes you can override:
  • 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, such as an avatar.
    • content. The content element.
    • message. The message text element.
    • reasoning. The reasoning disclosure.
    • reasoningHeader. The reasoning disclosure header.
    • reasoningIcon. The reasoning icon.
    • reasoningLabel. The reasoning label.
    • reasoningChevron. The reasoning disclosure chevron.
    • reasoningBody. The reasoning body.
    • reasoningText. The reasoning text.
    • 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 text area element.
JavaScript

Templates

You can customize parts of a widget’s UI using the Templates API. Each template includes an html function, which you can use as a tagged template. This function safely renders templates as HTML strings and works directly in the browser—no build step required. For details, see Templating your UI.
The html function is available in InstantSearch.js version 4.46.0 or later.
The actions, empty, loader, and messages.error templates receive a context object that groups the current chat state and callbacks.
  • context.messages, context.status, context.error, context.activePart. The conversation and where it stands. For the status values, see Status values.
  • context.open, context.maximized, context.isClearing. Panel state, for conditional rendering.
  • context.tools. The tools registered for the assistant.
  • context.sendMessage, context.regenerate, context.stop, context.setInput. Drive the conversation from a custom control.
  • context.onReload, context.onNewConversation, context.onClose. Regenerate a message, clear the conversation, or close the panel.
function
A template to customize the overall layout of the chat widget. Use chatInlineLayout() for an inline (non-overlay) layout, chatSidePanelLayout() for a side panel on the right side of the page, or provide a custom function.Use the side panel layout to keep the chat widget beside your page content on wider screens. Unlike the inline layout, the side panel requires an entry point to open the widget.By default, the side panel layout adjusts document.body. Set parentElement to a CSS selector to adjust another element.
  • When the side panel opens, the layout adds the value of --ais-chat-width to the selected element’s inline margin-right.
  • When the side panel closes, the layout restores the previous inline margin.
  • On wider screens, maximizing the chat widget changes the panel width to --ais-chat-maximized-width without increasing the reserved margin, so the maximized panel can overlap page content.
At viewport widths of 680px or less, the side panel fills the viewport. This breakpoint is based on the viewport width, not the width of parentElement.
JavaScript
string | function
The template to use for each result. This template receives an object containing a single record. You can use Algolia’s highlighting feature with the highlight function, directly from the template system.
JavaScript
function
The template to use for the welcome screen shown before the first message, when the chat doesn’t have any messages yet. Use it to display a greeting and starter prompts that send a message when clicked. It receives context, the supported API for shared chat state and callbacks:
  • context.sendMessage. Sends a message to the agent. Call it with { text } to submit a starter prompt as the first message.
  • context.status. The current chat status.
  • context.onClose. Dismisses the chat.
  • context.setInput. Sets the value of the prompt input without sending it.
The deprecated root-level sendMessage, status, onClose, and setInput parameters are also passed for compatibility. Read these values from context.
JavaScript
To render the default greeting (heading, subheading, and an optional banner) inside your template, use the exported chatGreeting template helper from instantsearch.js/es/templates.For a step-by-step walkthrough, see Show starter prompts on the chat welcome screen.
object
Templates to use for the header section of the widget.
  • clearLabelText. Accessible label for the clear button.
  • closeIcon. The close icon template.
  • closeLabel. Accessible label for the close button.
  • maximizeIcon. The maximize icon template. Receives a parameter containing { maximized: boolean } for conditional rendering.
  • maximizeLabelText. Accessible label for the maximize button.
  • minimizeIcon. The minimize icon template.
  • minimizeLabelText. Accessible label for the minimize button.
  • titleIcon. The title icon template (defaults to sparkles).
  • titleText. The title text to display.
JavaScript
object
Templates to use for the messages section of the widget.
  • copyToClipboardLabelText. Accessible label for the copy to clipboard action.
  • error. Custom template when there is an error generating a response. Guardrail fallback responses render as assistant messages, not through this template. 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. The template 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 errors where retrying fails again.
  • regenerateLabelText. Accessible label for the regenerate action.
  • scrollToBottomLabelText. Accessible label for the scroll to bottom button.
JavaScript
function
A template to customize the loader shown while waiting for an assistant response.It receives:
  • translations. The resolved loader translations.
  • context. The same context as shouldShowLoader, without defaultValue.
  • inline. Whether the loader renders inside an assistant message instead of in its own row. It’s true when loaderPosition is message-inline and an assistant message is available.
JavaScript
To keep the default loader and change only part of it, use the exported chatMessageLoader template helper from instantsearch.js/es/templates. For more information, see Customize the chat loader.
string | function
Text to display in the default loader. Pass a function to customize the text based on the turn context, which holds the same properties as shouldShowLoader receives, without defaultValue.
JavaScript
object
Templates to use for an individual message in the messages section of the widget.
  • messageLabelText. Accessible label for the message.
  • actionsLabelText. Accessible label for the actions container.
  • reasoningLabelText. Label for a reasoning disclosure.
JavaScript
object
Templates to use for messages that come from the chat assistant.
  • leading. The leading element, such as an avatar.
  • text. The template for each text part of the message. It replaces the default markdown rendering. It receives an object containing:
    • part. The text part to render. Its text property holds the text content.
    • message. The message the text part belongs to.
    • messages. The full conversation, when available.
    • status. The current chat status: 'ready', 'submitted', 'streaming', or 'error'.
    • partIndex. The index of the text part in the message’s parts array.
  • footer. The footer element of the message.
JavaScript
object
Templates to use for messages that come from the user.
  • leading. The leading element, such as an avatar.
  • text. The template for each text part of the message. It replaces the default markdown rendering. It receives the same object as the assistantMessage.text template.
  • footer. The footer element of the message.
JavaScript
object
Templates to use for the prompt section of the widget.
  • disclaimerText. Disclaimer text shown in the prompt footer.
  • emptyMessageTooltipText. The tooltip for the submit button when message is empty.
  • footer. Custom footer template.
  • header. Custom header template.
  • sendMessageTooltipText. The tooltip for the send button.
  • stopResponseTooltipText. The tooltip for the stop button.
  • textareaLabelText. Accessible label for the text area.
  • textareaPlaceholderText. Placeholder text for the text area.
JavaScript
string | function
The template to use for follow-up prompt suggestions. It receives:
  • suggestions. The list of suggestions.
  • onSuggestionClick. Call it with a suggestion when the user clicks it.
  • isLoading. Whether suggestions for the current turn are still on their way. Use it to render a placeholder before they arrive.
JavaScript
To customize the button that opens the chat, use the chatTrigger widget’s icon template instead.

HTML output

HTML

Streaming and resumption

Assistant responses stream over Server-Sent Events. The chat widget exposes the streaming lifecycle through its connector render state if you want to drive a custom UI.

Status values

The render state exposes status, 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

The render state exposes two methods:
  • 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: true to do it automatically.
To customize the stop behavior with connectChat, read status and stop from the render options:
JavaScript
To resume an ongoing stream after a reload, set resume: true on the widget, or call resumeStream() from a custom render function.
Last modified on August 28, 2026