React SDK

Integrate RelayKit video rooms into your React app using LiveKit's official React components. Your server generates tokens via the RelayKit API, and the client connects using the LiveKit SDK.

Installation

npm install livekit-client @livekit/components-react @livekit/components-styles

Architecture

┌─────────────┐     ┌──────────────┐     ┌─────────────────┐
│  Your React │────▶│  Your Server │────▶│  RelayKit API   │
│    App      │     │  (backend)   │     │ api.relaykit.live│
└──────┬──────┘     └──────────────┘     └────────┬────────┘
       │                                          │
       │  token                                   │ creates room
       ▼                                          ▼
┌──────────────┐                        ┌─────────────────┐
│ LiveKit SDK  │───────────────────────▶│  LiveKit Server  │
│ (WebRTC)     │     video/audio        │ (WebRTC infra)   │
└──────────────┘                        └─────────────────┘

Key principle: Your API key (rk_live_xxxx) stays on your server. The client only receives a short-lived token.

Server-side: Generate a token

// pages/api/get-token.ts (Next.js API route example)
export async function POST(req) {
  const { roomId, userId, userName } = await req.json();

  const response = await fetch('https://api.relaykit.live/api/v1/token', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.RELAYKIT_API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      roomId,
      participantIdentity: userId,
      participantName: userName,
    }),
  });

  const { data } = await response.json();
  return Response.json(data);
  // Returns: { token: "eyJ...", roomName: "abc-defg-hij" }
}

Client-side: Video Room Component

// components/VideoRoom.tsx
'use client';
import {
  LiveKitRoom,
  VideoConference,
  RoomAudioRenderer,
} from '@livekit/components-react';
import '@livekit/components-styles';

interface VideoRoomProps {
  token: string;
  serverUrl: string; // wss://livekit.relaykit.live
}

export default function VideoRoom({ token, serverUrl }: VideoRoomProps) {
  return (
    <LiveKitRoom
      token={token}
      serverUrl={serverUrl}
      connect={true}
      video={true}
      audio={true}
      style={{ height: '100vh' }}
      data-lk-theme="default"
    >
      <VideoConference />
      <RoomAudioRenderer />
    </LiveKitRoom>
  );
}

Full Example: Join Meeting Page

// app/meeting/page.tsx
'use client';
import { useState } from 'react';
import dynamic from 'next/dynamic';

const VideoRoom = dynamic(() => import('./VideoRoom'), { ssr: false });

export default function MeetingPage() {
  const [token, setToken] = useState('');
  const [name, setName] = useState('');

  async function joinRoom() {
    // 1. Create or get room from your server
    const roomRes = await fetch('/api/rooms', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ name: 'Team Standup' }),
    });
    const { data: room } = await roomRes.json();

    // 2. Get a token for this participant
    const tokenRes = await fetch('/api/get-token', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        roomId: room.id,
        userId: `user_${Date.now()}`,
        userName: name,
      }),
    });
    const { token } = await tokenRes.json();
    setToken(token);
  }

  if (token) {
    return <VideoRoom
      token={token}
      serverUrl="wss://livekit.relaykit.live"
    />;
  }

  return (
    <div>
      <input
        value={name}
        onChange={(e) => setName(e.target.value)}
        placeholder="Your name"
      />
      <button onClick={joinRoom}>Join Meeting</button>
    </div>
  );
}

Available Components

<VideoConference />

Full video conference UI with grid layout, controls, and participant list

<LiveKitRoom>

Provider component that manages the room connection

<RoomAudioRenderer />

Renders audio tracks from all participants

<ParticipantTile>

Individual participant video tile with name overlay

<ControlBar />

Camera, microphone, screen share, and leave controls

<TrackToggle>

Toggle button for camera/mic with icon states

LiveKit Components Reference

For the full list of components and hooks, see the LiveKit React Components documentation.