Skip to main content
This widget is and is subject to change in minor versions.
The chat widget shows a loader while a chat turn is in progress. You can control:
  • Where it appears, with loaderPosition or CSS.
  • When it appears, with shouldShowLoader.
  • Its timing, with loaderShowDelay and loaderMinDuration.
To change what the loader says or how it looks, see Customize the chat loader.

Render the loader inside the streaming message

By default, the loader appears in its own row after the last message. Set loaderPosition to message-inline to show it inside the streaming assistant message. Before the assistant sends its first part, the loader appears in its own row.
JavaScript

Move the loader with CSS

You can use CSS to reposition the default row loader (loaderPosition: "messages-end") within the chat panel. Show it above the conversation:
CSS
Keep it in view while the conversation scrolls behind it:
CSS
Pin it to the panel instead of the scroll area:
CSS
The pinned loader positions itself against .ais-ChatMessages, outside the scroll container, so it stays put while messages scroll. It also overlaps the end of the conversation, so add matching padding-bottom to .ais-ChatMessages-scroll. CSS can’t move the loader outside the message list. To show progress in your header or next to the prompt input, render your own indicator there.

Change when the loader shows

Use shouldShowLoader to customize when the loader appears. Relevant context properties include:
  • status. The chat status: submitted, streaming, ready, 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.
Return defaultValue for the cases you don’t handle, so you adjust the built-in behavior instead of rebuilding it. Keep the loader visible for the whole tool call, including while the tool streams its input:
JavaScript
Hide it for a tool that shows its own progress:
JavaScript
Returning false for every turn removes the loader. Give users another way to tell that the agent is working, such as an indicator in your own layout.

Tune the loader timing

During a turn, the loader can hide and reappear as the chat moves between different phases. Two options control these transitions:
  • loaderShowDelay. How long a renewed loading state must continue before the loader reappears. Defaults to 250 ms. The first time the loader appears in a turn, it isn’t delayed.
  • loaderMinDuration. The minimum time the loader remains visible while the turn is running. Defaults to 200 ms. This prevents the loader from briefly appearing and disappearing. When the turn ends, the loader hides immediately.
JavaScript
Raise loaderShowDelay if your agent alternates between short tool calls and text. Set it to 0 to show the loader immediately whenever a loading state starts.

Support assistive technology and reduced motion

The message list has aria-busy="true" while the chat status is submitted or streaming, so assistive technology can identify that the response is still being processed. The default loader’s entrance, spinner, and skeleton animations all stop under prefers-reduced-motion: reduce. Honor the same media query in your own loader.
Last modified on August 26, 2026