Embed React SDK Integration Guide
Overview
The Embed React SDK is a powerful voice-enabled AI agent library that provides real-time communication capabilities. This comprehensive guide will walk you through the complete integration process from installation to deployment.
Prerequisites
Node.js 18+
React 16.8+ or Next.js 12+
Modern browser with WebRTC support
This SDK requires proper setup of browser permissions and real-time communication dependencies.
Installation
Install the Embed React SDK using your preferred package manager:
npm install @revrag-ai/embed-react
Required CSS Import
CRITICAL: Always import the CSS file for proper styling. Missing this import will cause the widget to display incorrectly.
import '@revrag-ai/embed-react/dist/ai-assistant-widget.css' ;
SDK Initialization
useInitialize Hook
Initialize the SDK at the root level of your application using the useInitialize hook:
import React from 'react' ;
import { useInitialize , EmbedButton } from '@revrag-ai/embed-react' ;
import '@revrag-ai/embed-react/dist/ai-assistant-widget.css' ;
function App () {
const { isInitialized , error } = useInitialize ( 'your-api-key-here' );
if ( error ) {
console . error ( 'SDK initialization failed:' , error );
}
if ( ! isInitialized ) {
// Show loading screen while initializing
return < LoadingScreen /> ;
}
// Your app components
return < YourApp /> ;
}
Configuration Options
Property Type Required Description apiKeystring ✅ Your Embed API key
App Setup
1. Basic React Application
Add the EmbedButton component to your screen:
import React from 'react' ;
import { useInitialize , EmbedButton } from '@revrag-ai/embed-react' ;
import '@revrag-ai/embed-react/dist/ai-assistant-widget.css' ;
function App () {
const { isInitialized , error } = useInitialize ( 'your-api-key-here' );
if ( error ) return < div > Error: { error } </ div > ;
if ( ! isInitialized ) return < div > Initializing... </ div > ;
return (
< div >
< h1 > My Application </ h1 >
{ /* Your app content */ }
< EmbedButton />
</ div >
);
}
2. Next.js Integration
App Router (app/layout.tsx)
import { EmbedButton } from '@revrag-ai/embed-react' ;
import '@revrag-ai/embed-react/dist/ai-assistant-widget.css' ;
export default function RootLayout ({
children ,
} : {
children : React . ReactNode ;
}) {
return (
< html lang = "en" >
< body >
{ children }
< EmbedButton />
</ body >
</ html >
);
}
Pages Router (_app.tsx)
import { EmbedButton , useInitialize } from '@revrag-ai/embed-react' ;
import '@revrag-ai/embed-react/dist/ai-assistant-widget.css' ;
export default function MyApp ({ Component , pageProps }) {
useInitialize ( process . env . NEXT_PUBLIC_REVRAG_API_KEY );
return (
<>
< Component { ... pageProps } />
< EmbedButton />
</>
);
}
Event System
The SDK provides a powerful event system for sending user context and application state to the AI agent.
Available Events
import { EventKeys } from '@revrag-ai/embed-react' ;
// Available event keys:
EventKeys . USER_DATA // 'user_data' - User identity and profile
EventKeys . SCREEN_VIEW // 'screen_view' - Application state and context
EventKeys . OFFER_DATA // 'offer_data' - Application offer and context
EventKeys . FORM_STATE // 'form_state' - Form interactions and state
Event Usage Rules
CRITICAL REQUIREMENTS:
USER_DATA event MUST be sent first before any other events
USER_DATA must include app_user_id for user identification
EmbedButton should only be rendered AFTER USER_DATA event is sent
Other events can only be sent after USER_DATA is established
Event Methods
import { embed , EventKeys } from '@revrag-ai/embed-react' ;
// Send events
await embed . event ({
eventKey: EventKeys . USER_DATA , // or other event keys
data: { /* event data */ }
});
// Listen to events (optional)
// Events are automatically tracked through the system
Event Flow Example
// Example event flow
try {
// Step 1: Send user data first (required)
await embed . event ({
eventKey: EventKeys . USER_DATA ,
data: {
app_user_id: 'user123' ,
name: 'John Doe' ,
first_name: 'John' ,
last_name: 'Doe' ,
email: '[email protected] ' ,
}
});
// Step 2: Send context data (app_user_id auto-added)
await embed . event ({
eventKey: EventKeys . OFFER_DATA ,
data: {
current_offer: 'premium_plan' ,
discount: 20 ,
expires_at: '2024-12-31'
}
});
} catch ( error ) {
console . error ( 'Event error:' , error );
}
Usage Examples
Complete Integration Example
import React , { useEffect , useState } from 'react' ;
import {
useInitialize ,
EmbedButton ,
embed ,
EventKeys
} from '@revrag-ai/embed-react' ;
import '@revrag-ai/embed-react/dist/ai-assistant-widget.css' ;
export default function App () {
const [ userDataSent , setUserDataSent ] = useState ( false );
const { isInitialized , error } = useInitialize ( 'your-api-key-here' );
// Initialize user data when SDK is ready
useEffect (() => {
if ( isInitialized && ! userDataSent ) {
initializeUserData ();
}
}, [ isInitialized , userDataSent ]);
const initializeUserData = async () => {
try {
// STEP 1: Send user data first (REQUIRED)
await embed . event ({
eventKey: EventKeys . USER_DATA ,
data: {
app_user_id: 'user123' , // Required field
name: 'John Doe' ,
first_name: 'John' ,
last_name: 'Doe' ,
email: '[email protected] ' ,
subscription: 'premium' ,
joinedDate: '2024-01-15' ,
}
});
setUserDataSent ( true );
// STEP 2: Send initial screen state
await embed . event ({
eventKey: EventKeys . SCREEN_VIEW ,
data: {
screen: 'home' ,
timestamp: new Date (). toISOString (),
userActions: [],
}
});
// STEP 3: Send offer state
await embed . event ({
eventKey: EventKeys . OFFER_DATA ,
data: {
offer_data: [
{
offer_id: 3010 ,
is_enhanced: true ,
current_offer: 'premium_plan' ,
discount: 20 ,
// ...
}
]
}
});
console . log ( 'User data and initial state sent successfully' );
} catch ( error ) {
console . error ( 'Failed to initialize user data:' , error );
alert ( 'Failed to initialize voice agent' );
}
};
// Send screen state updates
const updateScreenState = async ( screenName , data = {}) => {
if ( ! userDataSent ) {
console . warn ( 'Cannot send screen state before user data' );
return ;
}
try {
await embed . event ({
eventKey: EventKeys . SCREEN_VIEW ,
data: {
screen: screenName ,
timestamp: new Date (). toISOString (),
... data ,
}
});
} catch ( error ) {
console . error ( 'Failed to update screen state:' , error );
}
};
// Handle initialization errors
if ( error ) {
console . error ( 'SDK initialization failed:' , error );
return (
< div style = { { textAlign: 'center' , padding: '50px' } } >
< h2 > Failed to initialize voice agent </ h2 >
< p > { error } </ p >
</ div >
);
}
// Show loading while initializing
if ( ! isInitialized ) {
return (
< div style = { { textAlign: 'center' , padding: '50px' } } >
< h2 > Initializing voice agent... </ h2 >
</ div >
);
}
return (
< div >
{ /* Your app content */ }
< YourAppComponents onScreenChange = { updateScreenState } />
{ /* Only render EmbedButton after user data is sent */ }
{ userDataSent && < EmbedButton /> }
</ div >
);
}
Positioning
// Bottom-right (default)
< EmbedButton />
// Bottom-left
< EmbedButton position = { { bottom: '24px' , left: '24px' } } />
// Top-right
< EmbedButton position = { { top: '24px' , right: '24px' } } />
// Custom units
< EmbedButton position = { { bottom: '2rem' , right: '2rem' } } />
Automatic Event Tracking
The library automatically tracks user interactions and sends them through the event system:
Automatic Tracking Features
Button Clicks : All button and submit inputs (tracked as EventKeys.FORM_STATE)
Form Inputs : Text fields, textareas, dropdowns (tracked as EventKeys.FORM_STATE)
Field Focus : When users focus on form fields (tracked as EventKeys.FORM_STATE)
Screen Views : Page navigation (React Router & Next.js) (tracked as EventKeys.SCREEN_VIEW)
Form Changes : Dropdowns, checkboxes, radio buttons (tracked as EventKeys.FORM_STATE)
The tracking system is automatically initialized when you use the useInitialize hook. All tracked events are sent with appropriate event keys without additional configuration.
Troubleshooting
Common Issues
User identity not found error
This error occurs when you try to send events before USER_DATA:
✅ Send USER_DATA event first with app_user_id
✅ Wait for the event to complete before sending other events
✅ Only render EmbedButton after USER_DATA is sent
// ❌ Wrong order
await embed . event ({
eventKey: EventKeys . SCREEN_VIEW ,
data: { screen: 'home' }
}); // Error!
// ✅ Correct order
await embed . event ({
eventKey: EventKeys . USER_DATA ,
data: { app_user_id: 'user123' }
});
await embed . event ({
eventKey: EventKeys . SCREEN_VIEW ,
data: { screen: 'home' }
}); // Works!
This issue is usually related to browser permissions or network configuration:
✅ Ensure HTTPS in production (WebRTC requirement)
✅ Check browser microphone permissions
✅ Verify LiveKit configuration
✅ Test network connectivity
// Check microphone permissions
navigator . mediaDevices . getUserMedia ({ audio: true })
. then (() => console . log ( 'Microphone access granted' ))
. catch ( err => console . error ( 'Microphone access denied:' , err ));
Verify automatic tracking is working:
✅ Verify useInitialize has been called
✅ Check browser console for event logs
✅ Use embedEvent.addCallback() to monitor events
✅ Ensure DOM elements have proper attributes
// Add event monitoring
import { embedEvent } from '@revrag-ai/embed-react' ;
embedEvent . addCallback (( event ) => {
console . log ( 'Event tracked:' , event );
});
User context not persisting
Check user data management:
✅ Check localStorage availability
✅ Verify USER_DATA event is sent first
✅ Ensure app_user_id is provided
✅ Check for browser storage restrictions
// Verify localStorage
try {
localStorage . setItem ( 'test' , 'test' );
localStorage . removeItem ( 'test' );
console . log ( 'localStorage available' );
} catch ( error ) {
console . error ( 'localStorage not available:' , error );
}
Network Debugging
// Monitor API calls
const originalFetch = window . fetch ;
window . fetch = function ( ... args ) {
console . log ( 'API Call:' , args [ 0 ]);
return originalFetch . apply ( this , args );
};
Best Practices
Event Optimization:
Debounce frequent events to avoid overwhelming the API
Batch related data in single events
Handle offline scenarios with retry logic
Store events locally when network is unavailable
Initialization Strategy:
Show loading states during SDK initialization
Handle initialization errors gracefully
Send USER_DATA as early as possible in the app lifecycle
Only render EmbedButton after successful initialization
Performance & Security:
Use lazy loading for large applications
Keep API keys secure with environment variables
Use HTTPS endpoints in production
Test widget interactions thoroughly
Monitor usage and performance metrics
Support
For additional help:
Last Updated: June 2025