---
title: React Integration
url: https://docs.kaltura.com/docs/conversational-agents/agentic-avatars-sdk/examples-react-integration
---

## React Integration

Integrate Kaltura Avatar with React using custom hooks and components.

### Custom Hook: useAvatar

```javascript
import { useState, useEffect, useRef, useCallback } from 'react';
import { KalturaAvatarSession } from '@unisphere/models-sdk-js';

export function useAvatar(apiKey, baseUrl) {
  const [session, setSession] = useState(null);
  const [sessionState, setSessionState] = useState('IDLE');
  const [connectionState, setConnectionState] = useState('DISCONNECTED');
  const [error, setError] = useState(null);
  const sessionRef = useRef(null);

  const createSession = useCallback(
    async (options) => {
      try {
        const avatarSession = new KalturaAvatarSession({ apiKey, baseUrl });

        avatarSession.on('stateChange', setSessionState);
        avatarSession.on('connectionChange', setConnectionState);
        avatarSession.on('error', setError);

        await avatarSession.createSession(options);
        sessionRef.current = avatarSession;
        setSession(avatarSession);
        return avatarSession;
      } catch (err) {
        setError(err);
        throw err;
      }
    },
    [apiKey, baseUrl]
  );

  const sayText = useCallback(async (text) => {
    if (!sessionRef.current) throw new Error('No active session');
    await sessionRef.current.sayText(text);
  }, []);

  const interrupt = useCallback(async () => {
    if (!sessionRef.current) throw new Error('No active session');
    await sessionRef.current.interrupt();
  }, []);

  const endSession = useCallback(async () => {
    if (!sessionRef.current) return;
    await sessionRef.current.endSession();
    setSession(null);
    sessionRef.current = null;
  }, []);

  // Cleanup on unmount
  useEffect(() => {
    return () => {
      if (sessionRef.current) {
        sessionRef.current.endSession();
      }
    };
  }, []);

  return {
    session,
    sessionState,
    connectionState,
    error,
    createSession,
    sayText,
    interrupt,
    endSession,
  };
}
```

### Usage Example

```jsx
import { useAvatar } from './hooks/useAvatar';

export default function AvatarComponent() {
  const { sessionState, connectionState, error, createSession, sayText, interrupt, endSession } = useAvatar('your-api-key', 'https://api.avatar.us.kaltura.ai/');

  const [text, setText] = useState('Hello!');

  const handleStart = async () => {
    await createSession({
      visualId: 'visual-123',
      voiceId: 'voice-456',
      videoContainerId: 'avatar-container',
    });
  };

  return (
    <div>
      <h2>Avatar Demo</h2>
      <div>State: {sessionState}</div>
      <div>Connection: {connectionState}</div>
      {error && <div>Error: {error.message}</div>}

      <div id="avatar-container" style={{ width: 512, height: 512 }} />

      <button onClick={handleStart} disabled={sessionState !== 'IDLE'}>
        Start
      </button>
      <button onClick={() => sayText(text)} disabled={sessionState !== 'READY'}>
        Speak
      </button>
      <button onClick={interrupt} disabled={sessionState !== 'READY'}>
        Interrupt
      </button>
      <button onClick={endSession} disabled={sessionState !== 'READY'}>
        End
      </button>
      <input value={text} onChange={(e) => setText(e.target.value)} />
    </div>
  );
}
```

### See Also

- **[Simple Client-Side Example](/docs/conversational-agents/agentic-avatars-sdk/examples-simple-client-side)** - Basic example
- **[Server Controlled Example](/docs/conversational-agents/agentic-avatars-sdk/examples-server-controlled)** - Production pattern
