Skip to main content

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

PropertyTypeRequiredDescription
apiKeystringYour 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:
  1. USER_DATA event MUST be sent first before any other events
  2. USER_DATA must include app_user_id for user identification
  3. EmbedButton should only be rendered AFTER USER_DATA event is sent
  4. 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: 'john@example.com',
    }
  });

  // 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: 'john@example.com',
          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>
  );
}

Widget Customization

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

Check these requirements:
  1. ✅ CSS file imported: import '@revrag-ai/embed-react/dist/ai-assistant-widget.css'
  2. ✅ SDK initialized successfully (isInitialized is true)
  3. ✅ Valid API key provided
  4. ✅ USER_DATA event sent first
  5. ✅ EmbedButton rendered after USER_DATA
// ✅ Correct implementation
const { isInitialized, error } = useInitialize('valid-api-key');

if (!isInitialized) return <div>Loading...</div>;
if (error) return <div>Error: {error}</div>;

return <EmbedButton />;
This error occurs when you try to send events before USER_DATA:
  1. ✅ Send USER_DATA event first with app_user_id
  2. ✅ Wait for the event to complete before sending other events
  3. ✅ 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:
  1. ✅ Ensure HTTPS in production (WebRTC requirement)
  2. ✅ Check browser microphone permissions
  3. ✅ Verify LiveKit configuration
  4. ✅ 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:
  1. ✅ Verify useInitialize has been called
  2. ✅ Check browser console for event logs
  3. ✅ Use embedEvent.addCallback() to monitor events
  4. ✅ Ensure DOM elements have proper attributes
// Add event monitoring
import { embedEvent } from '@revrag-ai/embed-react';

embedEvent.addCallback((event) => {
  console.log('Event tracked:', event);
});
Check user data management:
  1. ✅ Check localStorage availability
  2. ✅ Verify USER_DATA event is sent first
  3. ✅ Ensure app_user_id is provided
  4. ✅ 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