Skip to content

Latest commit

 

History

History

react

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 

README.md

openclaw-webchat-react

React hooks and components for OpenClaw Gateway. Build AI chat interfaces with ease.

Installation

npm install openclaw-webchat-react
# or
pnpm add openclaw-webchat-react
# or
yarn add openclaw-webchat-react

Quick Start

Using ChatWidget (Easiest)

Drop-in chat widget with built-in UI:

import { ChatWidget } from 'openclaw-webchat-react';

function App() {
  return (
    <ChatWidget
      gateway="wss://your-gateway.example.com/ws"
      token="your-auth-token"
      position="bottom-right"
      theme="light"
      title="AI Assistant"
    />
  );
}

Using Hook (Custom UI)

Build your own chat interface:

import { useOpenClawChat } from 'openclaw-webchat-react';

function CustomChat() {
  const {
    messages,
    isConnected,
    isLoading,
    streamingContent,
    error,
    send,
  } = useOpenClawChat({
    gateway: 'wss://your-gateway.example.com/ws',
    token: 'your-auth-token',
  });

  const [input, setInput] = useState('');

  const handleSend = async () => {
    if (!input.trim() || !isConnected) return;
    await send(input);
    setInput('');
  };

  return (
    <div>
      {/* Messages */}
      {messages.map((msg) => (
        <div key={msg.id} className={msg.role}>
          {msg.content}
        </div>
      ))}

      {/* Streaming indicator */}
      {isLoading && <div className="typing">{streamingContent || '...'}</div>}

      {/* Error display */}
      {error && <div className="error">{error.message}</div>}

      {/* Input */}
      <input
        value={input}
        onChange={(e) => setInput(e.target.value)}
        onKeyDown={(e) => e.key === 'Enter' && handleSend()}
        disabled={!isConnected || isLoading}
        placeholder={isConnected ? 'Type a message...' : 'Connecting...'}
      />
      <button onClick={handleSend} disabled={!isConnected || isLoading}>
        Send
      </button>
    </div>
  );
}

API Reference

ChatWidget Props

interface ChatWidgetProps {
  /** Gateway WebSocket URL (required) */
  gateway: string;

  /** Authentication token */
  token?: string;

  /** Authentication password (alternative to token) */
  password?: string;

  /** Widget position */
  position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left' | 'inline';

  /** Color theme */
  theme?: 'light' | 'dark' | 'auto';

  /** Widget title */
  title?: string;

  /** Input placeholder text */
  placeholder?: string;

  /** Start with widget open (floating mode only) */
  defaultOpen?: boolean;

  /** Custom CSS class */
  className?: string;

  /** Enable debug logging */
  debug?: boolean;

  // ... all OpenClawClientOptions are also supported
}

ChatWidget Render Props

<ChatWidget
  gateway="..."
  token="..."
  // Custom message renderer
  renderMessage={(message) => (
    <div className={`message ${message.role}`}>
      <strong>{message.role}:</strong> {message.content}
    </div>
  )}
  // Custom loading indicator
  renderLoading={(streamingContent) => (
    <div className="loading">
      AI is typing: {streamingContent}
    </div>
  )}
  // Callbacks
  onSend={(content) => console.log('Sent:', content)}
  onMessage={(message) => console.log('Received:', message)}
/>

useOpenClawChat Hook

const {
  messages,          // Message[] - all messages
  connectionState,   // ConnectionState - current connection state
  isConnected,       // boolean - is connected
  isLoading,         // boolean - is sending/receiving
  streamingContent,  // string - current streaming content
  error,             // Error | null - last error
  send,              // (content: string) => Promise<void>
  connect,           // () => Promise<void>
  disconnect,        // () => void
  clearMessages,     // () => void
  loadHistory,       // (limit?: number) => Promise<void>
  client,            // OpenClawClient | null - underlying client
} = useOpenClawChat(options);

Hook Options

interface UseOpenClawChatOptions {
  /** Gateway WebSocket URL (required) */
  gateway: string;

  /** Authentication token */
  token?: string;

  /** Auto-connect on mount (default: true) */
  autoConnect?: boolean;

  // ... all OpenClawClientOptions are also supported
}

Examples

Inline Chat

<ChatWidget
  gateway="wss://your-gateway.example.com/ws"
  token="your-token"
  position="inline"  // Renders inline, not floating
  theme="light"
/>

Dark Mode

<ChatWidget
  gateway="wss://your-gateway.example.com/ws"
  token="your-token"
  theme="dark"
/>

{/* Or auto-detect system preference */}
<ChatWidget
  gateway="wss://your-gateway.example.com/ws"
  token="your-token"
  theme="auto"
/>

Custom Positioning

<ChatWidget
  gateway="wss://your-gateway.example.com/ws"
  token="your-token"
  position="bottom-left"  // or 'top-right', 'top-left'
/>

With Manual Connection

function App() {
  const { isConnected, connect, disconnect, send } = useOpenClawChat({
    gateway: 'wss://your-gateway.example.com/ws',
    token: 'your-token',
    autoConnect: false,  // Don't connect automatically
  });

  return (
    <div>
      {isConnected ? (
        <button onClick={disconnect}>Disconnect</button>
      ) : (
        <button onClick={connect}>Connect</button>
      )}
    </div>
  );
}

TypeScript

Full TypeScript support with exported types:

import type {
  OpenClawClientOptions,
  Message,
  ConnectionState,
} from 'openclaw-webchat-react';

License

MIT