Build/Frontend

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/react

Basic 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:

PropertyTypeDescription
invoke(input) => Promise<TOutput>Execute the request
isLoadingbooleanTrue while request is pending
dataTOutput | undefinedLast successful response
errorError | nullLast error, if any
reset() => voidReset state to initial values

For GET requests (auto-fetches on mount):

PropertyTypeDescription
refetch() => Promise<TOutput>Manually refetch data
isLoadingbooleanTrue while request is pending
dataTOutput | undefinedLast successful response
errorError | nullLast error, if any
reset() => voidReset 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:

PropertyTypeDescription
isConnectedbooleanTrue when WebSocket is open
send(data: TInput) => voidSend a message
dataTOutput | undefinedLast received message
errorError | nullConnection or message error
close() => voidClose the connection
reset() => voidClear 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

HookUse CaseDirectionExamples
useAPIRequest/responseOne-timeSend a message, fetch user data, submit a form
useWebsocketBidirectional streamingClient ↔ ServerLive chat, multiplayer sync, shared editing
useEventStreamServer pushServer → ClientAI 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

Need Help?

Join our DiscordCommunity 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!