React SDK
The @avatarium/react package provides the <AvatariumEmbed> component for embedding AI avatars in React and Next.js apps.
Installation
npm install @avatarium/reactBasic usage
import { AvatariumEmbed } from '@avatarium/react';
function App() {
return (
<AvatariumEmbed
shortId="your-avatar-id"
mode="voice"
onReady={(data) => console.log('Avatar ready:', data)}
onStateChange={(state) => console.log('State:', state)}
style={{ width: 400, height: 600 }}
/>
);
}<AvatariumEmbed> props
Required
| Prop | Type | Description |
|---|---|---|
shortId | string | Your avatar's Short ID from the dashboard |
Optional
| Prop | Type | Default | Description |
|---|---|---|---|
host | string | https://avatarium.ai | API host URL |
mode | 'voice' | 'chat' | 'chat' | Interaction mode ('voice' enables microphone) |
style | CSSProperties | – | Container inline styles |
className | string | – | CSS class name |
Event callbacks
| Prop | Type | Description |
|---|---|---|
onReady | (data: { avatar: string; thumbnail?: string }) => void | Avatar loaded and ready |
onStateChange | (state: string) => void | State changed (idle, listening, speaking, thinking) |
onSpeakStart | () => void | Avatar started speaking |
onSpeakEnd | () => void | Avatar stopped speaking |
onTranscript | (text: string) => void | User speech transcribed |
onError | (error: string) => void | Error occurred |
Examples
Basic embed
import { AvatariumEmbed } from '@avatarium/react';
export function BasicEmbed() {
return (
<div style={{ width: '100%', maxWidth: 480, height: 640, margin: '0 auto' }}>
<AvatariumEmbed
shortId="demo-mia"
mode="voice"
onReady={(data) => console.log('Avatar ready:', data)}
onError={(error) => console.error('Avatar error:', error)}
/>
</div>
);
}Voice chat with state tracking
import { useState, useCallback } from 'react';
import { AvatariumEmbed } from '@avatarium/react';
type AvatarState = 'loading' | 'idle' | 'listening' | 'speaking' | 'thinking';
export function VoiceChat() {
const [state, setState] = useState<AvatarState>('loading');
const [isReady, setIsReady] = useState(false);
return (
<div style={{ maxWidth: 480, margin: '0 auto' }}>
<div style={{
display: 'flex', alignItems: 'center', gap: 8,
padding: '12px 16px', background: '#1a1a2e',
borderRadius: '12px 12px 0 0', color: '#fff',
}}>
<span style={{
width: 10, height: 10, borderRadius: '50%',
background: { loading: '#94a3b8', idle: '#22c55e', listening: '#3b82f6', speaking: '#a855f7', thinking: '#f59e0b' }[state],
}} />
<span style={{ fontSize: 14, textTransform: 'capitalize' }}>{state}</span>
</div>
<AvatariumEmbed
shortId="demo-mia"
mode="voice"
onReady={() => { setIsReady(true); setState('idle'); }}
onStateChange={(s) => setState(s as AvatarState)}
onError={(err) => console.error('Error:', err)}
style={{ width: '100%', height: 480, background: '#0f0f23' }}
/>
</div>
);
}Event handling with log panel
import { useState, useCallback, useRef } from 'react';
import { AvatariumEmbed } from '@avatarium/react';
export function EventHandling() {
const [logs, setLogs] = useState<{ time: string; event: string; data?: unknown }[]>([]);
const log = useCallback((event: string, data?: unknown) => {
setLogs((prev) => [...prev.slice(-99), {
time: new Date().toLocaleTimeString('en-US', { hour12: false }),
event,
data,
}]);
}, []);
return (
<div style={{ display: 'flex', gap: 16, maxWidth: 960, margin: '0 auto' }}>
<div style={{ flex: '0 0 400px' }}>
<AvatariumEmbed
shortId="demo-mia"
mode="voice"
onReady={(data) => log('ready', data)}
onStateChange={(state) => log('stateChange', { state })}
onSpeakStart={() => log('speakStart')}
onSpeakEnd={() => log('speakEnd')}
onError={(error) => log('error', { error })}
style={{ width: '100%', height: 500, borderRadius: 12 }}
/>
</div>
<pre style={{ flex: 1, background: '#111827', color: '#9ca3af', padding: 16, borderRadius: 12, overflow: 'auto', fontSize: 12 }}>
{logs.map((l, i) => `${l.time} ${l.event} ${l.data ? JSON.stringify(l.data) : ''}\n`)}
</pre>
</div>
);
}Next.js
The <AvatariumEmbed> component uses browser APIs, so it must be a client component in Next.js App Router.
app/avatar/page.tsx
'use client';
import { AvatariumEmbed } from '@avatarium/react';
export default function AvatarPage() {
return (
<div style={{ width: '100%', maxWidth: 480, height: 640, margin: '0 auto' }}>
<AvatariumEmbed
shortId="demo-mia"
mode="voice"
onReady={(data) => console.log('Avatar ready:', data)}
onError={(error) => console.error('Error:', error)}
/>
</div>
);
}With custom styling
components/AvatarCard.tsx
'use client';
import { AvatariumEmbed } from '@avatarium/react';
export default function AvatarCard() {
return (
<div style={{
maxWidth: 360, margin: '40px auto', borderRadius: 24,
overflow: 'hidden', boxShadow: '0 20px 60px rgba(0,0,0,0.15)',
}}>
<div style={{
padding: '16px 20px',
background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
color: '#fff',
}}>
<h2 style={{ margin: 0, fontSize: 18 }}>Meet Mia</h2>
<p style={{ margin: '4px 0 0', fontSize: 13, opacity: 0.8 }}>Your AI assistant – tap to talk</p>
</div>
<AvatariumEmbed shortId="demo-mia" mode="voice" style={{ width: '100%', height: 400 }} />
<div style={{ padding: '12px 20px', background: '#fff', textAlign: 'center', fontSize: 13, color: '#64748b' }}>
Powered by Avatarium
</div>
</div>
);
}How it works
<AvatariumEmbed> renders an <iframe> pointing to your avatar's URL and listens for postMessage events. The iframe handles all 3D rendering, voice, and AI processing.
This means:
- No WebGL dependencies in your bundle
- No WebSocket management
- Works in any React environment (CRA, Vite, Next.js, Remix)