AgentChat

Create a full chat surface with messages, status, and send/stop handlers. Get started at 21st.dev/agents/docs/get-started.

Hello there

Agent UI preview

Show me the latest changes.

Added tool cards and layout tweaks.

Can you also include a mobile preview?

Yes, the components are fully responsive!

Show me the error handling states too.

Included error cards and retry affordances.

Any accessibility updates in this pass?

Improved focus states, increased contrast, and added clearer labels.

import { AgentChat } from "@/lib/agent-ui";

const messages = [
  {
    id: "msg-1",
    role: "assistant",
    parts: [{ type: "text", text: "Welcome to Agent UI." }],
  },
];

const promptSuggestions = [
  { id: "write", label: "Write", value: "Write release notes for this change." },
  { id: "plan", label: "Plan", value: "Create a rollout plan in 5 steps." },
];

export function Example() {
  return (
    <div className="h-[560px] border border-border rounded-lg overflow-hidden bg-background">
      <AgentChat
        messages={messages}
        status="ready"
        onSend={() => {}}
        onStop={() => {}}
        showCopyToolbar
        emptyStatePosition="center"
        emptySuggestionsPlacement="empty"
        emptySuggestionsPosition="bottom"
        suggestions={{ items: promptSuggestions }}
      />
    </div>
  );
}
Getting Started
npm install 21st-sdk-react
Examples
Basic

Show me the latest status.

All systems are green.

<AgentChat
  messages={messages}
  status="ready"
  onSend={() => {}}
  onStop={() => {}}
/>
Empty centered
<AgentChat
  messages={[]}
  status="ready"
  onSend={() => {}}
  onStop={() => {}}
  emptyStatePosition="center"
/>
Empty centered + suggestions
<AgentChat
  messages={[]}
  status="ready"
  onSend={() => {}}
  onStop={() => {}}
  emptyStatePosition="center"
  emptySuggestionsPlacement="empty"
  emptySuggestionsPosition="bottom"
  suggestions={{ items: promptSuggestions }}
/>
With attachments

Show me the latest status.

All systems are green.

preview.png
spec.md3.1 KB
<AgentChat
  messages={messages}
  status="ready"
  onSend={() => {}}
  onStop={() => {}}
  attachments={{
    onAttach: () => {},
    images: [{ id: "img-1", filename: "preview.png", url: imageUrl }],
    files: [{ id: "file-1", filename: "spec.md", size: 3200 }],
    onRemoveImage: () => {},
    onRemoveFile: () => {},
  }}
/>
Copy toolbar

Show me the latest status.

All systems are green.

<AgentChat
  messages={messages}
  status="ready"
  onSend={() => {}}
  onStop={() => {}}
  showCopyToolbar
/>
API reference
Prop
Type
Required
messages
UIMessage[]
Yes
onSend
(message: { role: "user"; content: string }) => void
Yes
status
ChatStatus
Yes
onStop
() => void
Yes
error
Error
No
classNames
Partial<ChatClassNames>
No
slots
Partial<ChatSlots>
No
toolRenderers
Record<string, React.ComponentType<CustomToolRendererProps>>
No
attachments
{ onAttach?: () => void; images?: { id: string; filename: string; url: string; size?: number }[]; files?: { id: string; filename: string; size?: number }[]; onRemoveImage?: (id: string) => void; onRemoveFile?: (id: string) => void; onPaste?: (e: React.ClipboardEvent) => void; isDragOver?: boolean; }
No
showCopyToolbar
boolean
No
suggestions
InputSuggestions
No
emptyStatePosition
"default" | "center"
No
emptySuggestionsPlacement
"input" | "empty" | "both"
No
emptySuggestionsPosition
"top" | "bottom"
No
questionTool
{ submitLabel?: string; skipLabel?: string; allowSkip?: boolean; onAnswer?: (payload: { toolCallId?: string; question: QuestionConfig; answer: QuestionAnswer; }) => void; }
No
className
string
No
style
React.CSSProperties
No