React/Web Quick Start
This tutorial will guide you through integrating Fishjam into your React web application step by step.
By the end, you'll have a working video streaming web app and understand the core concepts.
What you'll build
A simple React web app that can join video calls and stream video between participants.
What you'll learn
- How to install and set up Fishjam for React
- How to join a room and start streaming
- How to display video from other participants
- How to manage media devices
Prerequisites
- React development environment set up
- Access to Fishjam Dashboard
Step 1: Install and set up
Install the package
- npm
- Yarn
- pnpm
- Bun
npm install @fishjam-cloud/react-client
yarn add @fishjam-cloud/react-client
pnpm add @fishjam-cloud/react-client
bun add @fishjam-cloud/react-client
Get your Fishjam ID and Sandbox API URL
- Log in to Fishjam Dashboard
- Navigate to the Sandbox tab
- Copy your Fishjam ID
- Copy your Sandbox API URL from the Sandbox API section
The Fishjam ID is required by FishjamProvider to connect to the media server. The Sandbox API URL is used by useSandbox to request test peer tokens.
Set up Fishjam context
Wrap your app in the FishjamProvider component:
// Check https://fishjam.io/app/ for your Fishjam ID constFISHJAM_ID = "YOUR_FISHJAM_ID";ReactDOM .createRoot (document .getElementById ("root")!).render ( <React .StrictMode > <FishjamProvider fishjamId ={FISHJAM_ID }> <App /> </FishjamProvider > </React .StrictMode >, );
Step 2: Join a room and start streaming
Create a component that joins a room and starts streaming:
importReact from "react"; import {useConnection ,useCamera ,useInitializeDevices ,useSandbox , } from "@fishjam-cloud/react-client"; constSANDBOX_API_URL = "YOUR_SANDBOX_API_URL"; export functionJoinRoomButton () { const {joinRoom } =useConnection (); const {selectCamera } =useCamera (); const {initializeDevices } =useInitializeDevices (); const {getSandboxPeerToken } =useSandbox ({sandboxApiUrl :SANDBOX_API_URL , }); consthandleJoinRoom = async () => { constroomName = "testRoom"; constpeerName = "testUser"; // For testing with the Sandbox API, use getSandboxPeerToken // For production apps, get the peerToken from your own backend instead constpeerToken = awaitgetSandboxPeerToken (roomName ,peerName ); // Start camera by selecting the first available camera awaitinitializeDevices ({enableAudio : false }); // or just initializeDevices(); if you want both camera and mic // Join the room awaitjoinRoom ({peerToken }); }; return <button onClick ={handleJoinRoom }>Join Room</button >; }
Step 3: Display other participants
Show video from other peers:
importReact from "react"; import {useEffect ,useRef } from "react"; import {usePeers } from "@fishjam-cloud/react-client"; functionVideoPlayer ({stream }: {stream :MediaStream | null | undefined }) { constvideoRef =useRef <HTMLVideoElement >(null);useEffect (() => { if (!videoRef .current ) return;videoRef .current .srcObject =stream ?? null; }, [stream ]); return <video ref ={videoRef }autoPlay playsInline />; } export functionParticipantsView () { const {remotePeers } =usePeers (); return ( <div > {remotePeers .map ((peer ) => ( <div key ={peer .id }> {peer .cameraTrack ?.stream && ( <VideoPlayer stream ={peer .cameraTrack .stream } /> )} </div > ))} </div > ); }
Step 4: Display your video
Show your own video stream:
importReact from "react"; import {useCamera } from "@fishjam-cloud/react-client"; export functionMyVideo () { const {cameraStream } =useCamera (); return <VideoPlayer stream ={cameraStream } />; }
Step 5: Handle connection status
Monitor your connection:
importReact from "react"; import {useConnection } from "@fishjam-cloud/react-client"; export functionConnectionStatus () { const {peerStatus } =useConnection (); return <div >Status: {peerStatus }</div >; }
Complete example
Here's a complete working app:
functionVideoPlayer ({stream }: {stream :MediaStream | null | undefined }) { constvideoRef =useRef <HTMLVideoElement >(null);useEffect (() => { if (!videoRef .current ) return;videoRef .current .srcObject =stream ?? null; }, [stream ]); return <video ref ={videoRef }autoPlay playsInline />; } functionVideoCall () { const {joinRoom ,peerStatus } =useConnection (); const {cameraStream } =useCamera (); const {remotePeers } =usePeers (); const {initializeDevices } =useInitializeDevices (); const {getSandboxPeerToken } =useSandbox ({sandboxApiUrl :SANDBOX_API_URL , }); const [isJoined ,setIsJoined ] =useState (false); consthandleJoin = async () => { constroomName = "testRoom"; constpeerName = `user_${Date .now ()}`; // Initialize devices first awaitinitializeDevices (); // For testing with the Sandbox API, use getSandboxPeerToken // For production apps, get the peerToken from your own backend instead constpeerToken = awaitgetSandboxPeerToken (roomName ,peerName ); awaitjoinRoom ({peerToken });setIsJoined (true); }; return ( <div > <h1 >Fishjam Video Call</h1 > <p >Status: {peerStatus }</p > {!isJoined && <button onClick ={handleJoin }>Join Room</button >} {cameraStream && ( <div > <h3 >Your Video</h3 > <VideoPlayer stream ={cameraStream } /> </div > )} <div > <h3 >Other Participants</h3 > {remotePeers .map ((peer ) => ( <div key ={peer .id }> {peer .cameraTrack ?.stream && ( <VideoPlayer stream ={peer .cameraTrack .stream } /> )} </div > ))} </div > </div > ); } export default functionApp () { return ( <FishjamProvider fishjamId ={FISHJAM_ID }> <VideoCall /> </FishjamProvider > ); }
Next steps
Now that you have a basic app working, explore these how-to guides:
- How to manage media devices
- How to implement livestreaming
- How to work with stream middleware
- How to handle custom sources
- Explore React examples
Or learn more about Fishjam concepts: