ReactJS Classroom Workshop Tutorial
Build an interactive classroom with mediasfu-reactjs@4.3.0. The supplied room
includes participants, messages, polls, breakouts, whiteboard, media, and exit.
Prerequisites
- Node.js 18 to 20, React 18, HTTPS or
localhost, and teacher/learner profiles. - Authenticated create/join routes with teacher and learner role policy.
Project files
{"private":true,"scripts":{"dev":"vite"},"dependencies":{"mediasfu-reactjs":"4.3.0","react":"18.2.0","react-dom":"18.2.0"},"devDependencies":{"@types/react":"18.3.24","@types/react-dom":"18.3.7","@vitejs/plugin-react":"4.3.4","typescript":"5.9.3","vite":"5.4.19"}}
import { ModernMediasfuGeneric, type CreateRoomOnMediaSFUType, type JoinRoomOnMediaSFUType } from 'mediasfu-reactjs';
async function postRoom<T>(url: string, payload: unknown): Promise<T> { const response = await fetch(url, { method: 'POST', credentials: 'same-origin', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); if (!response.ok) throw new Error(`Room request failed (HTTP ${response.status}).`); return response.json() as Promise<T>; }
const createRoom: CreateRoomOnMediaSFUType = ({ payload }) => postRoom('/api/mediasfu/create-room', payload); const joinRoom: JoinRoomOnMediaSFUType = ({ payload }) => postRoom('/api/mediasfu/join-room', payload);
export default function App() { return <main><header><h1>Classroom workshop</h1><p>Open Messages, Polls, Breakouts, or Whiteboard from the room.</p></header><ModernMediasfuGeneric connectMediaSFU={true} createMediaSFURoom={createRoom} joinMediaSFURoom={joinRoom} /></main>; }
import { StrictMode } from 'react'; import { createRoot } from 'react-dom/client'; import App from './App'; createRoot(document.getElementById('root')!).render(<StrictMode><App /></StrictMode>);
<!doctype html><html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width,initial-scale=1" /><title>Classroom workshop</title></head><body><div id="root"></div><script type="module" src="/src/main.tsx"></script></body></html>
import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; export default defineConfig({ plugins: [react()] });
{"compilerOptions":{"target":"ES2022","lib":["DOM","ES2022"],"strict":true,"module":"ESNext","moduleResolution":"Bundler","skipLibCheck":true,"noEmit":true,"jsx":"react-jsx"},"include":["src"]}
For isolated local development, the backend may use restricted, revocable credentials that are never committed. Before distribution, external testing, or production rooms, reusable Cloud credentials must remain on the backend.
Backend
Implement the two API routes using the complete public production room credential boundary. The backend authorizes teacher and learner roles; the browser never receives a MediaSFU Cloud credential.
Run
npm install
npm run dev
Expected result
Teacher and learner join, exchange a message, complete a poll, enter and leave a breakout, and open/close the whiteboard according to room permissions.
Recovery
Keep a learner in the main room if a breakout move fails. Do not silently replay an interrupted poll or whiteboard action. Refresh current room state first.
Cleanup
End polls and breakouts, close whiteboard state, clear app-owned drafts, then use participant Leave or the authorized host End flow. Expire backend authority.