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
- Log in to Fishjam Dashboard
- Navigate to your Sandbox environment
- Copy your Fishjam ID
Set up Fishjam context
Wrap your app in the FishjamProvider
component:
// Check https://fishjam.io/app/ for your Fishjam ID const
FISHJAM_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:
import
React from "react"; import {useConnection ,useCamera ,useInitializeDevices ,useSandbox , } from "@fishjam-cloud/react-client"; export functionJoinRoomButton () { const {joinRoom } =useConnection (); const {selectCamera } =useCamera (); const {initializeDevices } =useInitializeDevices (); const {getSandboxPeerToken } =useSandbox (); consthandleJoinRoom = async () => { constroomName = "testRoom"; constpeerName = "testUser"; // In sandbox environment, you can get the peer token from our sandbox API // In production environment, you need to get it from your backend 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:
import
React 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:
import
React 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:
import
React 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:
function
VideoPlayer ({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 (); const [isJoined ,setIsJoined ] =useState (false); consthandleJoin = async () => { constroomName = "testRoom"; constpeerName = `user_${Date .now ()}`; // Initialize devices first awaitinitializeDevices (); // In sandbox environment, you can get the peer token from our sandbox API // In production environment, you need to get it from your backend 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
Or learn more about Fishjam concepts: