React Hooks
Call your API routes from React with useAPI, useWebsocket, and useEventStream
Call your API routes from React components using type-safe hooks from @agentuity/react.
Installation
bun add @agentuity/reactBasic Usage with useAPI
The useAPI hook calls your API routes with full type safety:
import { AgentuityProvider, useAPI } from '@agentuity/react';
function ChatForm() {
const { invoke, isLoading, data, error } = useAPI('POST /api/chat');
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
const formData = new FormData(e.currentTarget);
const message = formData.get('message') as string;
try {
await invoke({ message });
} catch (err) {
// Error is also available via the error state
console.error('API call failed:', err);
}
};
return (
<form onSubmit={handleSubmit}>
<input name="message" placeholder="Type a message..." disabled={isLoading} />
<button type="submit" disabled={isLoading}>
{isLoading ? 'Sending...' : 'Send'}
</button>
{error && <p>Error: {error.message}</p>}
{data && <p>Response: {data.response}</p>}
</form>
);
}
export default function App() {
return (
<AgentuityProvider>
<ChatForm />
</AgentuityProvider>
);
}For POST/PUT/PATCH/DELETE requests:
| Property | Type | Description |
|---|---|---|
invoke | (input) => Promise<TOutput> | Execute the request |
isLoading | boolean | True while request is pending |
data | TOutput | undefined | Last successful response |
error | Error | null | Last error, if any |
reset | () => void | Reset state to initial values |
For GET requests (auto-fetches on mount):
| Property | Type | Description |
|---|---|---|
refetch | () => Promise<TOutput> | Manually refetch data |
isLoading | boolean | True while request is pending |
data | TOutput | undefined | Last successful response |
error | Error | null | Last error, if any |
reset | () => void | Reset state to initial values |
Real-Time with useWebsocket
For bidirectional real-time communication, use useWebsocket:
import { useWebsocket } from '@agentuity/react';
import { useEffect, useState } from 'react';
function RealtimeChat() {
const [messages, setMessages] = useState<string[]>([]);
const { isConnected, send, data } = useWebsocket('/api/chat');
// Handle incoming messages
useEffect(() => {
if (data) {
setMessages((prev) => [...prev, `Server: ${data}`]);
}
}, [data]);
const handleSend = (message: string) => {
setMessages((prev) => [...prev, `You: ${message}`]);
send({ message });
};
return (
<div>
<p>Status: {isConnected ? 'Connected' : 'Connecting...'}</p>
<ul>
{messages.map((msg, i) => (
<li key={i}>{msg}</li>
))}
</ul>
<button onClick={() => handleSend('Hello!')}>Send Hello</button>
</div>
);
}Auto-Reconnection
WebSocket connections automatically reconnect with exponential backoff if the connection drops. Messages sent while disconnected are queued and sent when the connection is restored.
Return values:
| Property | Type | Description |
|---|---|---|
isConnected | boolean | True when WebSocket is open |
send | (data: TInput) => void | Send a message |
data | TOutput | undefined | Last received message |
error | Error | null | Connection or message error |
close | () => void | Close the connection |
reset | () => void | Clear error state |
Streaming with useEventStream
For one-way streaming from server to client, use Server-Sent Events:
import { useEventStream } from '@agentuity/react';
function LiveStatus() {
const { isConnected, data, error } = useEventStream('/api/status');
if (!isConnected) {
return <p>Connecting to status feed...</p>;
}
if (error) {
return <p>Error: {error.message}</p>;
}
return (
<div>
<p>Live Status: {data?.status ?? 'Waiting for update...'}</p>
<p>Last updated: {data?.timestamp ?? '-'}</p>
</div>
);
}When to Use SSE
Use useEventStream when you only need server-to-client updates (e.g., progress indicators, live dashboards, notifications). For bidirectional communication, use useWebsocket.
Choosing the Right Hook
| Hook | Use Case | Direction | Examples |
|---|---|---|---|
useAPI | Request/response | One-time | Send a message, fetch user data, submit a form |
useWebsocket | Bidirectional streaming | Client ↔ Server | Live chat, multiplayer sync, shared editing |
useEventStream | Server push | Server → Client | AI token streaming, build logs, live metrics |
Request Options
Hooks accept options for customizing requests:
const { invoke } = useAPI('POST /api/chat');
// Add query parameters
await invoke(input, {
query: new URLSearchParams({ version: '2' }),
});
// Add custom headers
await invoke(input, {
headers: { 'X-Custom-Header': 'value' },
});
// Cancel request with AbortSignal
const controller = new AbortController();
await invoke(input, { signal: controller.signal });Next Steps
- Provider Setup: Configure
AgentuityProviderfor deployments - Advanced Hooks: Custom handlers for WebSocket and SSE
- Deployment Scenarios: Choose where your frontend lives
Need Help?
Join our Community for assistance or just to hang with other humans building agents.
Send us an email at hi@agentuity.com if you'd like to get in touch.
Please Follow us on
If you haven't already, please Signup for your free account now and start building your first agent!