Step 1: Create a container for Jitsi
The Jitsi iframe needs a container element of a pre-defined height and width to render into.
import React from "react";
const VideoConference = () => {
const jitsiContainerId = "jitsi-container-id";
return <div id={jitsiContainerId} style={{ height: 720, width: "100%" }} />;
};
export default VideoConference;
Step 2: Load the Jitsi Meet API Library Script
Unfortunately, this isn't available as an NPM module, and so we're gonna have to go old-school here. We first create a <script/>
element with its src
pointing to the source of the API library. We then append this to the document's body.
The script takes an onload
callback, which runs once the script has been loaded and executed. In order to convert this into a promise, we pass it the resolve method of an empty promise.
const VideoConference = () => {
// const jitsiContainerId = ...
const loadJitsiScript = () => {
let resolveLoadJitsiScriptPromise = null;
const loadJitsiScriptPromise = new Promise((resolve) => {
resolveLoadJitsiScriptPromise = resolve;
});
const script = document.createElement("script");
script.src = "https://meet.jit.si/external_api.js";
script.async = true;
script.onload = resolveLoadJitsiScriptPromise
document.body.appendChild(script);
return loadJitsiScriptPromise;
};
// return ( ... )
};
Let me know in the comments if you have a more elegant way of promise-ifying the script loading part! 😄
Step 3: Load the Jitsi IFrame
Once the script is loaded, it adds a class named JitsiMeetExternalAPI
to the global window
object. Instantiating this class loads the Jitsi iframe and returns an API object, which we can later be used to customise and control the Jitsi interface.
const VideoConference = () => {
// const jitsiContainerId = ...
const [jitsi, setJitsi] = React.useState({});
// const loadJitsiScript = () => { ... }
const initialiseJitsi = async () => {
if (!window.JitsiMeetExternalAPI) {
await loadJitsiScript();
}
const _jitsi = new window.JitsiMeetExternalAPI("meet.jit.si", {
parentNode: document.getElementById(jitsiContainerId),
});
setJitsi(_jitsi)
};
React.useEffect(() => {
initialiseJitsi();
return () => jitsi?.dispose?.();
}, []);
// return ( ... )
};
Our initialiseJitsi
function is called only once when the component is first rendered, and Jitsi's dispose()
method is called when the component is destroyed.
Good!
This should give you a barebones setup. Here's a CodeSandbox with what we've done so far.
Configure Jitsi
There are quite a few options to configure your Jitsi iframe. For example, if you are rolling your own Jitsi server, you can specify its URL endpoint instead of meet.jit.si
. The object from instantiating JitsiMeetExternalAPI
also provides quite a few methods and event listeners to configure and control the Jitsi interface. Check out Jitsi's docs for all the options, methods and events available.
Top comments (4)
Great, thanks for the post!
here is a suggestion for simplifying your promise a bit
Awesome!, you saved my day...
Thanks for the tutorial.
Only one thing would change and that is the way to access the container element. Wouldn't it be more elegant to use the 'useRef' hook?
Some comments may only be visible to logged-in visitors. Sign in to view all comments. Some comments have been hidden by the post's author - find out more