Mastering the Huddle01 SDK - 8 tips to keep in mind

Vraj DesaiVraj Desai
6 min read

While working on the Huddle01 SDK and incorporating feedback from our developer community, I also collated a few helpful tips and tricks for building with the Huddle01 SDK to make the development process easier and faster for you.

Most of the information I'll be sharing in this blog post is especially relevant for Next JS. Although you can apply the same concepts in React, keep in mind that server-side rendering is not possible with React alone.

So, without further ado, let's dive in and get started ๐Ÿš€

1. Stay up-to-date with the latest SDK version

We regularly update our SDKs to provide the best developer experience possible. Therefore, I highly recommend checking if you have the latest version of the Huddle01 SDK installed. If you don't you can easily upgrade it by running the following command.

pnpm update @huddle01/react@latest

2. Call APIs from the server side

Whenever you need to use APIs such as create-room, live-meetings, get-rooms, etc., it is always recommended to make the API calls from the server side instead of the client side. Calling these APIs from the client side may pose a risk of exposing your PRIVATE_KEY. If you are using Next JS, you can make the API calls from getServerSideProps or create an API route using a Serverless function.

createRoom.ts

// Next.js API route support: <https://nextjs.org/docs/api-routes/introduction>
import type { NextApiRequest, NextApiResponse } from "next";

interface RoomDetails {
  message: string;
  data?: {
    roomId: string;
  };
}

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  const response = await fetch("<https://api.huddle01.com/api/v1/create-room>", {
    method: "POST",
    body: JSON.stringify({
      title: req.body.title,
      startTime: req.body.startTime,
        hostWallets: req.body.hostWallets
      }),
    }),
    headers: {
      "Content-Type": "application/json",
      "x-api-key": process.env.API_KEY as string,
    },
  });
  const data: RoomDetails = await response.json();
  res.status(200).json({ roomId: data?.data?.roomId });
}

Make sure to store your API_KEY in the .env file and add it to the .gitignore to prevent it from being exposed. If you are using the App router in Next JS, there is no need to use a Serverless function. Instead, you can simply create a new server-side component that calls this API and returns the roomId.

3. Using useEventListener to handle events

In general, we typically use the useEffect hook and check the state to see if it has changed. However, in our SDKs, we provide a built-in event listener that allows you to listen to various events such as room:joined, room:peer-left, app:cam-on, app:mic-on, and more. You can find more information about the supported events here. The useEventListener function will be particularly useful when you want to set up your current video stream or perform certain actions on certain events.

import { useEventListener } from "@huddle01/react/hooks"

...
useEventListener("room:joined", () => {
    // Write you logic here on lobby joined
}
...

4. Displaying your viewport

Many builders who use our SDK encounter issues when trying to display their viewport after fetching a video stream. To display your viewport, you need to create a videoRef and set it with the stream obtained from calling fetchVideoStream.

import { useVideo, useEventListener } from "huddle01/react/hooks";
import { useEffect, useRef } from 'react';

...
const { fetchVideoStream } = useVideo();

useEventListener("app:cam-on", (stream) => {
    if (stream && videoRef.current) {
            videoRef.current.srcObject = stream;
        }
});

...
// jsx
<>
<video ref={videoRef} autoPlay />
<button onClick={fetchVideoStream}> fetch video </button>
</>
...

Here, when you click on fetchVideo, it will call the fetchVideoStream method and trigger the app:cam-on event. This event returns the stream that we can use to set videoRef.

5. Showing peers' viewport

Displaying the viewport of other peers (participants) in the room is straightforward using ready-to-use components from our SDK. Our SDK provides two components: one for video and one for audio.

import { Video, Audio } from "@huddle01/react/components";
import { usePeers } from "@huddle01/react/hooks";

const { peers } = usePeers();

...
//jsx
Object.values(peers).map(({ peerId, cam, mic }) => (
    <>
    {cam && (
        <Video key={peerId} track={cam} peerId={peerId} />
    )}

    {mic && (
        <Audio key={peerId} track={mic} peerId={peerId} />
    )}
    </>
    )
)}
...

6. Managing routes for Lobby and Room

When joining a room, it is recommended to follow a proper flow by creating two separate pages: one for the lobby and another for the room. In the lobby, users can set their avatar and display name. The files should be organized as follows:

pages

  • [roomId]

    • lobby.tsx (This page is for the Lobby)

    • index.tsx (This page is for the Room)

When a user navigates to {url}/[roomId], we first check if the room has been joined or not using the isRoomJoined variable obtained from the useRoom hook. If isRoomJoined is false, the user will be redirected to {url}/[roomId]/lobby.

import { useRoom } from "@huddle01/react/hooks";
import { useRouter } from "next/router";

const { isRoomJoined } = useRoom();

const { query } = useRouter();

useEffect(() => {
    if (!isRoomJoined && query.roomId) {
      push(`/${query.roomId}/lobby`);
      return;
    }
  }, [isRoomJoined, query.roomId]);

7. Switching media devices

Our SDK provides built-in methods to retrieve a list of available media devices. The useVideo and useAudio functions include the enumerateCamDevices and enumerateMicDevices hooks, respectively, which return lists of available camera and audio devices. Once you have obtained this list, you can display it in a dropdown menu and prompt the user to select a device. After the user has made a selection, you can retrieve the deviceId of the chosen device and pass it as an argument to the fetchVideoStream and fetchAudioStream methods.

import { useVideo, useAudio } from "@huddle01/react/hooks";
import { useEffect } from "react";

const { fetchVideoStream, enumerateCamDevices, camDevices } = useVideo();
const { fetchAudioStream, enumerateMicDevices, micDevices } = useAudio();

useEffect(() => {
    enumerateCamDevices();
    enumerateMicDevices();
}, [])

...
// jsx
<>
<button onClick={() => fetchVideoStream(camDevices[0].deviceId)} fetch video <button/>
<button onClick={() => fetchAudioStream(micDevices[0].deviceId)} fetch audio <button/>
</>
...

8. Sending Data to Peers

You can send any type of text-based data to all peers in the room. This functionality is useful for implementing features like sending reactions, speaker requests, and more. One cool feature that you can implement using the sendData function from our SDK is chat. You can create your chat UI and utilise the sendData function to send messages. The best part is that you can even send data to specific peers by passing an array of peerIds.

import { useAppUtils } from "@huddle01/react/app-utils";
import { useEventListener } from "@huddle01/react/hooks";

const { sendData } = useAppUtils();

// listen to receive data event and get data from it
useEventListener("room:data-received", (data) => {
  console.log(data);
});

const sendReaction = (emoji) => {
  // Here "*" represents all peers in the room
  sendData("*", {emoji: emoji });
};

const sendMessage = (peerId: string) => {
    // Send data to specific peer
    sendData(peerId, { message: "Hello World!"} );
};

Happy Hacking โš’๏ธ

Thank you so much for taking the time to read this article! ๐Ÿ˜Š I hope you've enjoyed it and have learned something new. I'm excited to see what amazing projects you'll build using the Huddle01 SDKs. If you have any questions or need assistance, feel free to reach out to us on our Discord. We're here to help you 24/7. And don't forget to check out our docs for even more information about our SDKs.

Happy coding! ๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ป

0
Subscribe to my newsletter

Read articles from Vraj Desai directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Vraj Desai
Vraj Desai