React hook for building chat interfaces with AI language models.
import { useChat } from 'ai/react';
export default function Chat() {
const { messages, sendMessage, status } = useChat();
return (
<div>
{messages.map((message) => (
<div key={message.id}>
<strong>{message.role}:</strong> {message.content}
</div>
))}
<button
onClick={() => sendMessage({ content: 'Hello!' })}
disabled={status === 'in_progress'}
>
Send
</button>
</div>
);
}
Parameters
A unique identifier for the chat. If not provided, a random ID will be generated.
When provided, the useChat hook with the same id will share states across components.
An existing Chat instance. When provided, the hook will use this instance instead of creating a new one.
api
string
default:"/api/chat"
The API endpoint that accepts a { messages } object and returns a stream of tokens of the AI chat response.
Initial messages to be used in the chat.
onToolCall
(toolCall: ToolCall) => void
Callback function to be called when a tool call is received.
onData
(data: JSONValue) => void
Callback function to be called when data is received from the stream.
onFinish
(message: UIMessage) => void
Callback function to be called when the response is complete.
Callback function to be called when an error occurs.
sendAutomaticallyWhen
(message: UIMessage) => boolean
Function that determines whether to automatically send a message.
Custom throttle wait in milliseconds for the chat messages and data updates.
Default is undefined, which disables throttling.
Whether to resume an ongoing chat generation stream.
Returns
The current array of chat messages.
setMessages
(messages: UIMessage[] | ((messages: UIMessage[]) => UIMessage[])) => void
Update the messages state locally. This is useful when you want to edit the messages on the client,
and then trigger the regenerate method manually to regenerate the AI response.
sendMessage
(message: CreateUIMessage) => void
Send a new message to the API endpoint.
Regenerate the last AI response.
Resume a previously stopped stream.
status
'idle' | 'in_progress' | 'awaiting_message'
The current status of the chat.
'idle': No active generation
'in_progress': Currently generating a response
'awaiting_message': Waiting for user input
The error object if an error occurred.
addToolResult
(toolResult: ToolResult) => void
Add a tool result to the chat. Deprecated: use addToolOutput instead.
addToolOutput
(toolOutput: ToolOutput) => void
Add a tool output to the chat.
addToolApprovalResponse
(response: ToolApprovalResponse) => void
Add a tool approval response to the chat.
Examples
Basic chat interface
import { useChat } from 'ai/react';
export default function Chat() {
const { messages, sendMessage, status } = useChat();
return (
<div>
<div>
{messages.map((message) => (
<div key={message.id}>
<strong>{message.role}:</strong>
{message.content}
</div>
))}
</div>
<button
onClick={() => sendMessage({ content: 'Hello!' })}
disabled={status === 'in_progress'}
>
{status === 'in_progress' ? 'Sending...' : 'Send'}
</button>
</div>
);
}
import { useChat } from 'ai/react';
import { useState } from 'react';
export default function Chat() {
const { messages, sendMessage, status } = useChat();
const [input, setInput] = useState('');
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
if (input.trim()) {
sendMessage({ content: input });
setInput('');
}
};
return (
<div>
<div>
{messages.map((message) => (
<div key={message.id}>
<strong>{message.role}:</strong>
{message.content}
</div>
))}
</div>
<form onSubmit={handleSubmit}>
<input
value={input}
onChange={(e) => setInput(e.target.value)}
placeholder="Type a message..."
/>
<button type="submit" disabled={status === 'in_progress'}>
Send
</button>
</form>
</div>
);
}
import { useChat } from 'ai/react';
export default function Chat() {
const { messages, sendMessage, addToolOutput, status } = useChat({
onToolCall: async (toolCall) => {
if (toolCall.toolName === 'getWeather') {
// Execute the tool
const weather = await fetch(
`/api/weather?location=${toolCall.input.location}`
).then((res) => res.json());
// Add the result
addToolOutput({
toolCallId: toolCall.toolCallId,
output: weather,
});
}
},
});
return (
<div>
{messages.map((message) => (
<div key={message.id}>
{message.content}
{message.toolInvocations?.map((tool) => (
<div key={tool.toolCallId}>
Tool: {tool.toolName}
{tool.state === 'result' && (
<div>Result: {JSON.stringify(tool.result)}</div>
)}
</div>
))}
</div>
))}
</div>
);
}
With custom API endpoint
import { useChat } from 'ai/react';
export default function Chat() {
const { messages, sendMessage } = useChat({
api: '/api/custom-chat',
});
return (
<div>
{messages.map((message) => (
<div key={message.id}>{message.content}</div>
))}
</div>
);
}