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-sdk
Initialization of project
Head over to API Keys Page and connect your wallet to get your project credentials:
API Key
projectId
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/v1/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.