Building a React App with Huddle01
Walkthrough
The following guide explains how you can integrate audio/video into your React web-app seamlessly using the Huddle01 React SDK in your Next.js App.
Install @huddle01/react in your react app
To power your React dApp with audio/video communication using Huddle01, install the following packages:
pnpm i @huddle01/react @huddle01/server-sdkInitialization of project
Head over to API Keys Page and connect your wallet to get your project credentials:
API KeyprojectId
Once done, initialize your project by creating an instance of HuddleClient and pass it in HuddleProvider. Make sure that you wrap HuddleProvider in your root i.e.
import type { AppProps } from "next/app";
import { HuddleClient, HuddleProvider } from "@huddle01/react";
const huddleClient = new HuddleClient({
projectId: process.env.NEXT_PUBLIC_PROJECT_ID!,
options: {
// `activeSpeakers` will be most active `n` number of peers, by default it's 8
activeSpeakers: {
size: 12,
},
},
});
export default function App({ Component, pageProps }: AppProps) {
return (
<HuddleProvider client={huddleClient}>
<Component {...pageProps} />
</HuddleProvider>
);
}Room Creation
You need a roomId for joining a room, which you can get by calling the Create Room API.
Make sure that you are calling this API from server side.
If you are using pages router you can create an API route or for app router you can easily create a server side component.
import axios from 'axios';
import type { NextApiRequest, NextApiResponse } from 'next';
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
try {
const { data } = await axios.post(
'https://api.huddle01.com/api/v2/sdk/rooms/create-room',
{
title: 'Huddle01 Meet',
},
{
headers: {
'Content-Type': 'application/json',
'x-api-key': process.env.API_KEY as string,
},
}
);
res.status(200).json(data);
} catch (error) {
res.status(500).json(error);
}
};
export default handler;Generating the Access Token
Once, roomId is generated you need to generate accessToken which is required to join room.
import type { NextApiRequest, NextApiResponse } from 'next';
import { AccessToken, Role } from '@huddle01/server-sdk/auth';
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
const { roomId } = req.query;
if (!roomId) {
return res.status(400).json({ error: 'roomId is required' });
}
const accessToken = new AccessToken({
apiKey: process.env.API_KEY!,
roomId: roomId as string,
role: Role.HOST,
permissions: {
admin: true,
canConsume: true,
canProduce: true,
canProduceSources: {
cam: true,
mic: true,
screen: true,
},
canRecvData: true,
canSendData: true,
canUpdateMetadata: true,
}
});
const token = await accessToken.toJwt();
return res.status(200).json({ token });
}Joining and leaving the room
You need roomId and accessToken to join room using joinRoom method from useRoom hook.
It's recommended that you send roomId over a url like YOUR_URL/roomId.
import { useRoom } from '@huddle01/react/hooks';
const App = () => {
const { joinRoom, leaveRoom } = useRoom({
onJoin: () => {
console.log('Joined the room');
},
onLeave: () => {
console.log('Left the room');
},
});
return (
<div>
<button onClick={() => {
joinRoom({
roomId: 'YOUR_ROOM_ID',
token: 'YOUR_ACCESS_TOKEN'
});
}}>
Join Room
</button>
<button onClick={leaveRoom}>
Leave Room
</button>
</div>
);
};Sending media across participants
To produce video,audio, and screenShare streams, you can use useLocalVideo,useLocalAudio and useLocalScreenShare hook.
import {
useLocalVideo,
useLocalAudio,
useLocalScreenShare,
} from "@huddle01/react/hooks";
const App = () => {
const { stream, enableVideo, disableVideo, isVideoOn } = useLocalVideo();
const { stream, enableAudio, disableAudio, isAudioOn } = useLocalAudio();
const { startScreenShare, stopScreenShare, shareStream } =
useLocalScreenShare();
return (
<div>
{/* Webcam */}
<button
onClick={() => {
isVideoOn ? disableVideo() : enableVideo();
}}
>
Fetch and Produce Video Stream
</button>
{/* Mic */}
<button
onClick={() => {
isAudioOn ? disableAudio() : enableAudio();
}}
>
Fetch and Produce Audio Stream
</button>
{/* Screen Share */}
<button
onClick={() => {
shareStream ? stopScreenShare() : startScreenShare();
}}
>
Fetch and Produce Screen Share Stream
</button>
</div>
);
};Advanced: Using the useLocalMedia hook
import { useLocalMedia } from "@huddle01/react/hooks";
const App = () => {
const { fetchStream } = useLocalMedia();
return (
<div>
{/* Webcam */}
<button onClick={() => fetchStream({ mediaDeviceKind: "cam" })}>
Fetch Cam Stream
</button>
{/* Mic */}
<button onClick={() => fetchStream({ mediaDeviceKind: "mic" })}>
Fetch Mic Stream
</button>
</div>
);
};Receiving the audio and video streams
We can use hooks such as useRemoteAudio, useRemoteVideo and useRemoteScreenShare for consuming audio, video and screen-share streams.
import {
usePeerIds,
useRemoteVideo,
useRemoteAudio,
useRemoteScreenShare
} from '@huddle01/react/hooks';
import { Audio, Video } from '@huddle01/react/components';
import { FC } from 'react';
interface RemotePeerProps {
peerId: string;
}
const RemotePeer: FC<RemotePeerProps> = ({ peerId }) => {
const { stream: videoStream } = useRemoteVideo({ peerId });
const { stream: audioStream } = useRemoteAudio({ peerId });
const { videoStream: screenVideoStream, audioStream: screenAudioStream } = useRemoteScreenShare({ peerId });
return (
<div>
{videoStream && <Video stream={videoStream}>}
{audioStream && <Audio stream={audioStream}>}
{screenVideoStream && <Video stream={screenVideoStream}>}
{screenAudioStream && <Audio stream={screenAudioStream}>}
</div>
)
}
const ShowPeers = () => {
const { peerIds } = usePeerIds({ roles: [Role.HOST, Role.CO_HOST] }); // Get Hosts And Cohost's peerIds
return (
<div>
{peerIds.map(peerId => {
return <RemotePeer peerId={peerId} />
})}
</div>
)
}
export default ShowPeers;You're all set! Happy Hacking! 🎉
For more information, please refer to the SDK Reference.