Virtual Classroom - React
A virtual classroom lets a teacher run a lesson for students who join from laptops, tablets and phones. A class of up to a few dozen students who talk and come on camera runs as a video call, and the lesson can be recorded and transcribed for students who missed it.
For lectures with hundreds of students, see Virtual Lectures. For supervised exams, see Online Proctoring.
If you are new to VideoSDK, start with Concept and Architecture and Integrate React SDK, and check Supported Browsers for the devices your students use.
VideoSDK runs the live video, audio, whiteboard, screen share, chat, recording and transcription for the lesson. Your application owns the class schedule, the course roster and enrollment, and the learning platform around the lesson.
Set Up the Class Session
Prepare the room and generate participant tokens on your backend before the lesson begins.
- Keep the class schedule in your backend: VideoSDK does not keep the class schedule, the course roster or the enrollment, so keep them in your learning management system. Create the room for the lesson, issue the tokens when it is due, and move students to the pre-call screen when the lesson is about to start.
- Create a room: Use the Create a Room API to create a room for each lesson. Use the returned
roomIdto attach the lesson to the course in your class schedule. - Validate the room: Before issuing student tokens, use the Validate a Room API to ensure the room is valid and available for the lesson. If validation fails, do not issue the tokens, and report the failure to your class schedule.
- Configure participant permissions: Set
allow_joinandallow_modin the teacher's token so the teacher can join directly, mute students and request that they turn their camera on. Setallow_joinin student tokens so students join directly, orask_joinwhen the teacher approves each student from the waiting lobby. IncluderoomIdandparticipantIdin every token payload, withversionset to2. See Authentication and Tokens. - Gate controls by role: Features such as recording, screen sharing, the whiteboard and removing a participant are available to all participants by default. Show these controls only in the teacher's console to keep lesson actions under the teacher's control, and keep chat, private messages and raised hands available to students.
Configure the Students' Devices and Network
Students join lessons from laptops, tablets and phones, often over home or mobile networks, and need a setup that works without technical help. Prepare their devices and assess network quality before the lesson.
Check Devices and Network Before the Class
- Check permissions and devices: Provide a pre-call screen where students can grant camera and microphone permissions, preview their camera, and test their microphone and speaker. Use
checkPermissions()andrequestPermission()from theuseMediaDevicehook to manage permissions. UsegetCameras()andgetMicrophones()to list available devices, andonDeviceChangedto refresh the list when a headset is connected or disconnected. See Precall Setup. - Assess network quality: Use
runPreCallTest()to evaluate uplink and downlink quality on a scale from 1 (BAD) to 5 (EXCELLENT), along with the factors affecting each score. Use the results to select an appropriate starting media configuration and help students understand what to expect from their connection. See Precall Setup. - Apply the verified setup: Pass the selected camera and microphone devices, their enabled states, and the chosen media configuration to
MeetingProviderso the meeting starts with the setup the student verified. Refer to the Precall Setup guide for recommended configurations based on the test results. The configuration can include a custom camera track created withcreateCameraVideoTrack(). See Optimize Video Tracks. - Join after pre-call checks: Set
joinWithoutUserInteractiontotrueonMeetingProviderif the student has already chosen to join from the pre-call screen. See Join Meeting. - Start students with the microphone off: When the teacher decides who speaks, set
micEnabledtofalseonMeetingProviderin the student's application so every student joins muted, while the teacher's application keeps its own setting. The teacher can then request a student's microphone when they raise a hand. For a small group where students speak freely, keep the microphone setting the student chose on the pre-call screen. See Initialise Meeting.
Reduce Noise and Distractions from the Student's Side
- Use a virtual background and noise suppression: Use the Virtual Background plugin to blur or replace the student's surroundings and the Noise Suppression plugin to reduce background noise from their microphone. In classes with many active microphones, reducing background noise across participants makes the overall audio clearer. Virtual backgrounds are supported on desktop browsers.
Configure the Teacher's Console
The teacher runs the lesson from a console, teaching on the whiteboard and slides, taking questions and keeping order. The console should provide controls for admitting students, teaching, engaging the class and controlling the lesson.
Prepare the Teacher's Environment Before the Class
- Check devices and network: Have the teacher complete the pre-call checks, including
runPreCallTest(), before admitting students. This helps identify device or connectivity issues before the lesson begins. See Precall Setup. - Apply a virtual background: Use the Virtual Background plugin to blur the teacher's background or replace it with an image, such as a classroom backdrop, so students see a consistent view whether the teacher is in a staff room or at home. Virtual backgrounds are supported on desktop browsers.
- Suppress background noise: Use the Noise Suppression plugin on the teacher's microphone to reduce background noise and help students hear the lesson clearly, even from a busy staff room.
Admit Students from the Lobby
The waiting lobby only holds students until the teacher admits them. Your system is responsible for the class schedule and enrollment, as described in Set Up the Class Session.
- Admit students: When students join with
ask_jointokens, they wait in the lobby until the teacher admits them. HandleonEntryRequestedin the teacher's console to receive each student'sparticipantIdandname, check them against the roster, then callallow()to admit them. Both the teacher and the student receiveonEntryRespondedwith the admissiondecision. See Waiting Lobby. - Handle a denied request: If the teacher denies the request, display an appropriate message to the student. Call
leave()in the student's application to disconnect them, since they remain connected until your application does so. See Leave or End Meeting.
Teach on the Whiteboard and Share Slides
- Collaborate on the whiteboard: Use
startWhiteboard()from theuseWhiteboardhook to open a shared canvas for every participant. While it is open, the hook'swhiteboardUrlholds the address your application embeds, andstopWhiteboard()closes the canvas when the exercise is over. See Whiteboard. - Share slides: Use
enableScreenShare()from theuseMeetinghook to share slides and worked examples, which students receive throughscreenShareStream. Share a Chrome tab with its audio when the slides include a video clip, so the clip is heard as well as seen. See Screen Share and Screen Share with Audio.
Engage Students During the Lesson
- Take questions in chat: Use
publish()from theusePubSubhook to let students ask questions without interrupting the lesson, so the teacher can answer them between slides. Setpersisttotruewhen publishing a message that should still be displayed when a student rejoins or a new student joins after some time. Persisted messages can also be downloaded as CSV from the VideoSDK session dashboard for the lesson record. See Chat using PubSub. - Support private conversations: Pass the recipient's
participantIdin thesendOnlyoption ofpublish()to send a message to one person, so a student can ask the teacher for help and the teacher can reply without the rest of the class seeing it. See Private Chat. - Share handouts and files: Use
uploadBase64File()from theuseFilehook to upload a worksheet or a PDF to VideoSDK's temporary storage. Share the returnedfileUrlwith the class by publishing it withpublish()over PubSub, and usefetchBase64File()to retrieve the file on a student's device. Temporary files are deleted when the meeting ends, so save anything students need to keep in your own storage. See File Sharing. - Let students raise their hands: If the teacher decides who speaks, use a dedicated PubSub topic so a student can raise a hand, and list students in the teacher's console in the order they raise their hands. The teacher can then request that student's microphone with
enableMic(), as described in Control the Class, and clear the student's indicator once they have spoken. See Chat using PubSub. - Poll the class: Use polls to quickly assess students' understanding of a topic. Publish the poll question and answer options over PubSub, then aggregate responses and display the results on each screen. See Audience Polls.
- Keep shared state synchronized: Use the Realtime Store for small state that should stay consistent across participants, such as the current slide, an open poll, or the list of students allowed to unmute. Use
setValue()andgetValue()from theuseRealtimeStorehook to write and read values, andonValueChangedto respond to updates. After a reconnect, listen toonMeetingStateChangedand read the current values again withgetValue()when the state returns toCONNECTED. See Realtime Store. - Indicate who is speaking: Use
onSpeakerChangedfrom theuseMeetinghook to identify the active speaker and help students follow who is speaking during a discussion. See Active Speaker Indication.
Control the Class
- Manage classroom audio and video: Before a presentation or discussion, the teacher can mute a single student by calling
disableMic()from theuseParticipanthook, or mute every student at once before moving on. To invite a student to speak or turn on their camera, useenableMic()orenableWebcam(), which send a request that the student accepts throughonMicRequestedoronWebcamRequestedin their application. Muting remote participants requires theallow_modpermission in the teacher's token. See Mute All Participants and Toggle Remote Participant Media. - Remove a disruptive student: If a student repeatedly disrupts the lesson, use
remove()from theuseParticipanthook to remove them from the meeting. See Remove Participant. - End the lesson: When the class is over, call
end()from theuseMeetinghook to end the meeting for all participants. See Leave or End Meeting.
Configure the Call Screen on Both Sides
These components are built into both the student's application and the teacher's console.
Display the Class
- Render each participant's video: Use the
VideoPlayercomponent to render each participant's video. It requests the video quality that matches the tile size and pauses streams for tiles that scroll out of view. The teacher then appears large and clear on student screens while classmates stay in small tiles, and the component mirrors the local preview. See Display Audio and Video. - Choose a suitable layout: For classes with dozens of students, choose a layout that keeps the most relevant content visible. Use a paginated grid to display students in groups, a sidebar layout to give more space to the whiteboard or shared slides, or a spotlight layout to highlight the active speaker. See Layout and Grid Management.
- Keep the class visible with Picture-in-Picture: Use Picture-in-Picture to keep the lesson visible in a floating window when either side moves to another screen, such as a student opening an assignment or the teacher opening the lesson plan. See Picture-in-Picture Mode.
Control Your Own Media and Devices
- Give microphone and camera controls: Provide microphone and camera controls in the teacher's console using
muteMic()andunmuteMic()andenableWebcam()anddisableWebcam()from theuseMeetinghook, so the teacher can mute between sections. Give students the same controls when they manage their own media. If the teacher decides who speaks, leave the microphone control out of the student's screen and let students answer the teacher's microphone request. See Mute / Unmute Mic and On / Off Camera. - Allow device changes: Provide in-call controls for the teacher, and for students when they manage their own media, to switch microphones or cameras if a device stops working or someone plugs in a headset. Use
getMics()andgetWebcams()from theuseMeetinghook to list available devices and theirdeviceIdandlabel. Pass the selecteddeviceIdtochangeMic()orchangeWebcam(). See Change Input Device.
Show Participant Status
- Track attendance: Use
onParticipantJoinedandonParticipantLeftfrom theuseMeetinghook to update each screen as students join and leave, and to keep the attendance list in the teacher's console up to date. Theparticipantsmap provides the current list of participants in the meeting. See Participant Events. - Show microphone and camera status: Use
micOnandwebcamOnfrom theuseParticipanthook to indicate whether each participant's microphone and camera are enabled. See Display Audio and Video. - Monitor the incoming video stream: Use
onStreamStateChangedfrom theuseStreamhook to detect when a participant's video stream becomes active, stuck, or frozen, so a student can check their connection when the teacher's video freezes and the teacher can see which students are affected. See Monitoring Remote Streams.
Keep the Session Reliable
These controls apply to both the student's application and the teacher's console.
Handle Network Changes During the Lesson
Network conditions can change during a lesson. Students may use home or mobile networks, while teachers may connect through school or campus networks. VideoSDK adapts video quality to available bandwidth and provides network and media events that help your application respond to changing conditions.
- Keep both sides informed: Use the relevant quality events to notify students and the teacher when network conditions affect call quality and when conditions improve. See Monitoring Network Quality for available events and Optimize for Low Bandwidth Networks for recommendations before and during the call.
- Show the connection state: Use
onMeetingStateChangedfrom theuseMeetinghook to follow the meeting connection throughCONNECTING,CONNECTED,RECONNECTINGandDISCONNECTED. Show a reconnecting indicator on both screens while the state isRECONNECTING, so students and the teacher know the lesson is recovering rather than over, and return to your class schedule screen when it reachesDISCONNECTED. See Meeting Connection State Events.
Handle Errors and Follow Best Practices
- Handle SDK errors: Use
onErrorfrom theuseMeetinghook to receive error information when a meeting operation fails. Display actionable feedback in the student's application and the teacher's console, and send relevant diagnostic details to your monitoring service so failures across lessons stay visible to your team. Avoid including student data in logs. See Error Events. - Follow integration guidelines: Review the User Experience Guidelines and Developer Experience Guidelines to build a reliable, accessible classroom experience.
Recording
Configure recording, storage delivery, and encryption based on what the lesson record needs. You can start recording when the lesson begins and configure transcription alongside it. If recording is mandatory, verify that it has started before proceeding with the lesson. The recording file, the transcript and the summary are delivered once the lesson ends, so students who missed it can catch up and everyone can revise. The recording's delivery destination and encryption depend on your configured storage and encryption settings.
Choose the Recording Type
VideoSDK offers three types of recording. Choose the one that matches what your lesson record needs. See Recording Overview.
- Meeting recording: Records the entire lesson, every participant and shared content, into one file with a composed layout. See Start and Stop.
- Participant recording: Records one participant's audio and video into a single file, such as the teacher alone for a clean copy of the lecture. Start it with the Start Participant Recording API, and use the matching participant recording API to stop it. See Participant Recording (Individual).
- Participant track recording: Records a single audio or video track of one participant as its own file. Start it with the Start Track Recording API, and use the matching track recording API to stop it. See Participant Track Recording.
Record the Lesson
- Start recording automatically: If the lesson must be recorded from the beginning, show the class a consent notice before the lesson starts, then add a
recordingentry toautoStartConfigwhen creating the room with the Create a Room API. Use this entry to configure transcription and the recordingconfigas needed. See Create a Room. - Wait for recording confirmation: Show a loader on both screens until the recording starts. The backend receives the
recording-startedwebhook, while the applications receiveonRecordingStateChangedwithRECORDING_STARTED. If the teacher starts recording manually usingstartRecording()from theuseMeetinghook, show the same loader until the started status arrives. See Start and Stop and Webhook and Events. - Handle recording failures: VideoSDK sends the
recording-failedwebhook if recording fails while starting, during the lesson, or while stopping. If recording fails at the start and recording is mandatory, do not proceed with the lesson. If recording is optional, you can continue without it. If recording fails during the lesson, you can retry or end the session. To close the room automatically when recording fails, configure theonFailureoption as described below. See Recording Failed Webhook. - Close the room automatically: If recording is mandatory, configure VideoSDK to close the room when recording fails. Add an
onFailureentry to therecordingsection ofautoStartConfig, or include it in the request body when starting recording from your backend. Setactiontoclose-roomand configurewaitTimein seconds. We recommend30seconds. See theonFailureparameter and example request body in Create a Room and Start Recording. - Stop the recording and store the file: The recording stops automatically when the lesson ends. To stop it earlier, call
stopRecording()from theuseMeetinghook or the Stop Recording API from your backend. Your backend receives therecording-stoppedwebhook with thefileUrl,filePathandsessionId, so it can attach the file to the lesson record for students who missed the class. To look the file up later, use the Fetch Recordings API to list the recordings of a room or the Fetch a Recording API to retrieve one by its id. See Webhook and Events.
Store Recordings in Your Own Storage
- Configure your own storage: Use Configure Recording Storage in the dashboard to deliver recordings to your own AWS S3, Azure Blob or GCP bucket. It is set per API key and includes a test step.
- Upload with a presigned URL: When stored credentials are not allowed, generate a presigned URL on your backend and pass it to the Start Recording API, so the recording is uploaded to one object for a limited time.
VideoSDK uploads recordings to your storage with the credentials you set up. If your storage only accepts uploads from approved IP addresses, you will need to approve VideoSDK's static IP addresses. Contact us to request them.
Encrypt and Decrypt Recordings
- Encrypt recordings at rest: Turn on Recording Encryption for the API key in the dashboard, under Cloud Storage Configuration, and provide an RSA public key. Each recording is encrypted with its own AES key before upload.
AES-256-GCMis recommended. - Decrypt with your private key: Each recording arrives as three files: the encrypted recording, the wrapped AES key and a metadata file. Decrypt them on your side with your private key. The guide includes a Node.js example.
Recording Encryption and transcription cannot be enabled together on one API key, since transcription runs on unencrypted recordings. Decide per API key which your lesson record needs before configuring either.
Transcription
Live captions help students who are hard of hearing or learning in a second language, while the post-lesson transcript and summary become revision notes. Transcription is not available for an API key with Recording Encryption enabled.
Show Live Captions
- Display live captions: Use
startTranscription()from theuseTranscriptionhook to start real-time transcription. Each line is delivered throughonTranscriptionTextas the teacher speaks. CallstopTranscription()when captions are no longer needed. See Realtime Transcription.
Generate the Transcript and Summary
- Generate a post-lesson transcript and summary: Pass a
transcriptionconfiguration tostartRecording(), setenabledtotrue, and provide asummary.promptthat specifies the sections your students need, such as topics covered, key points and homework. Retrieve the transcript and summary using the Fetch Post Transcriptions & Summary API or the webhook URL provided tostartRecording(). See Post Transcription & Summary.
Choose the Language
- Set the spoken language: Pass the appropriate language code to
startTranscription(). The default isen. See Supported Languages for available codes, including regional variants such asen-IN,hi, andes-419. - Translate captions when needed: If some students learn in a second language, use Realtime Translation to help them follow the lesson in their own language.
Meet Compliance Requirements
Configure these session-wide controls to align your classroom with your institution's data protection policies and regional requirements.
| Requirement | Control |
|---|---|
| Keep media within a region | Use Geo Fencing to restrict connections to VideoSDK servers in your specified regions, regardless of the student's location. See Geo Fencing. |
| Allow or restrict access by location | Use Geo IP Restriction to allow or deny access based on the student's IP address and your geographic rules. See Geo IP Restriction. |
| Encrypt media end to end | Use E2EE to encrypt media on the sender's device and decrypt it only on the receiver's device, preventing intermediaries, including VideoSDK servers, from accessing the media. Your application is responsible for generating and distributing encryption keys. See E2EE Setup. |
| Meet regulatory requirements | VideoSDK offers GDPR compliance with EU data residency and a Data Processing Agreement for schools and universities in the EU, and SOC 2 Type II, ISO 27001 and CERT-IN for institutional vendor reviews. GDPR compliance and the Data Processing Agreement are available as add-ons. |
If E2EE is enabled and you want to record or transcribe the lesson, use a custom recording template. See Customize Recording UI.
- Recording: Build the template with the React or JavaScript SDK and enable E2EE in it using the same key provider and shared key as your application, so the template can decrypt the media for recording. Deliver the key securely from your backend to the template over HTTPS rather than including it in the
templateUrl, then start the recording using the template'stemplateUrl. - Transcription: Use the same template recording for the post-lesson transcript and summary, since post transcription runs on the recording file. Realtime transcription is not available when E2EE is enabled.
Firewall and Debugging
Teachers often connect through school or campus networks, and some students may use restricted networks as well. Configure firewall rules before the first lesson to ensure the required VideoSDK services are reachable. If a session fails to connect, use the checks below to identify potential network restrictions.
Allow VideoSDK Traffic Through Your Firewall
-
Allow VideoSDK domains: The simplest approach is to allow all subdomains of
*.videosdk.liveover TCP and UDP on all ports. This covers the API, signaling, media, and TURN servers. See Firewall Setup. -
Allow specific hosts and ports: If your network policy requires explicit firewall rules, allow the following hosts and ports. VideoSDK can use the fallback transport when the primary connection is unavailable.
Server Host Primary Fallback API api.videosdk.liveTCP 443 — Signaling *.rm.videosdk.live, or the regional hosts listed in the Firewall Setup guideTCP 443 — Media media.videosdk.liveUDP 40000–60000 TCP 40000–60000 TURN turn.videosdk.liveUDP and TCP 3478 TCP 443 Also allow
sdk.videosdk.liveover TCP 443 if your console loads the SDK or the PubSub worker from the VideoSDK CDN. The full-access policy already covers it. -
Allow the PubSub worker in your Content Security Policy: PubSub runs in a web worker created from a
blob:URL. If the teacher's console runs under a strict Content Security Policy, allowblob:in theworker-srcdirective, or passpubsubWorkerUrltoMeetingProviderto load a pre-built worker from the VideoSDK CDN or your own domain. See CSP policy for PubSub. -
Use Cloud Proxy for restricted networks: If the required ports cannot be opened, use Cloud Proxy to route media through the proxy servers you specify. Choose UDP over TCP (the default), Force UDP, or Force TCP according to your network restrictions.
Debug Connection Issues
- Test the network before the first lesson: Run
runPreCallTest()from the campus network after configuring the firewall. The test checks whether a call can transmit media in both directions. If it fails despite internet access, review the required hosts and ports above. See Precall Setup. - Check UDP connectivity: Set
preferredProtocoltoTCP_ONLYinMeetingProviderand try connecting again. If the call succeeds over TCP but fails with the defaultUDP_OVER_TCPconfiguration, investigate whether UDP traffic is blocked on the media or TURN ports. You can also configure Cloud Proxy for the affected network. - Inspect connection errors: Use
onErrorfrom theuseMeetinghook to capture the error code and message when a connection fails. Use this information to investigate whether the failure occurred during the API, signaling, or media stage, and forward relevant diagnostics to your monitoring service to identify affected networks. See Error Events. - Verify media flow: Use
getTransportStats()from theuseParticipanthook to inspect transport statistics and check whether traffic is flowing in both directions. If one direction shows no bitrate, investigate the corresponding network path and firewall rules. See Monitoring Transport Stats. - Collect connection logs: Call
setLogLevel()withConstants.LogLevel.DEBUGto collect detailed diagnostics while reproducing the issue. After troubleshooting, restore the log level toINFOorNONEas appropriate. See Log Level.
API Reference
The API references for all the methods and events utilized in this guide are provided below.
- runPreCallTest()
- setLogLevel()
- MeetingProvider
- micEnabled
- createCameraVideoTrack()
- VideoPlayer
- checkPermissions()
- requestPermission()
- getCameras()
- getMicrophones()
- onDeviceChanged
- leave()
- end()
- muteMic()
- unmuteMic()
- enableWebcam()
- disableWebcam()
- enableScreenShare()
- getMics()
- changeMic()
- getWebcams()
- changeWebcam()
- participants
- enableMic()
- disableMic()
- enableWebcam()
- remove()
- getTransportStats()
- micOn
- webcamOn
- screenShareStream
- startWhiteboard()
- stopWhiteboard()
- whiteboardUrl
- publish()
- uploadBase64File()
- fetchBase64File()
- setValue()
- getValue()
- onValueChanged
- onEntryRequested
- onEntryResponded
- onParticipantJoined
- onParticipantLeft
- onSpeakerChanged
- onMeetingStateChanged
- onError
- onWebcamRequested
- onMicRequested
- onStreamStateChanged
- startRecording()
- stopRecording()
- onRecordingStateChanged
- startTranscription()
- stopTranscription()
- onTranscriptionText
- Create a Room
- Validate a Room
- Start Participant Recording
- Start Track Recording
- Start Recording
- Stop Recording
- Fetch Recordings
- Fetch a Recording
- Fetch Post Transcriptions & Summary
- Webhooks List
Got a Question? Ask us on discord

