Skip to main content

Vue Classroom Workshop Tutorial

Build an interactive classroom with mediasfu-vue@1.1.1. The supplied room includes participants, messages, polls, breakouts, whiteboard, media, and leave.

Prerequisites

  • Node.js 18 to 20, Vue 3, HTTPS or localhost, and teacher/learner profiles.
  • Authenticated create/join routes with teacher and learner policy.

Project files

package.json
{"private":true,"scripts":{"dev":"vite"},"dependencies":{"mediasfu-vue":"1.1.1","vue":"3.5.13"},"devDependencies":{"@vitejs/plugin-vue":"5.2.1","typescript":"5.9.3","vite":"5.4.19"}}
src/room-gateway.ts
import type { CreateJoinRoomResult, CreateRoomOnMediaSFUType, JoinRoomOnMediaSFUType } from 'mediasfu-vue'; async function postRoom(url: string, payload: unknown): Promise<CreateJoinRoomResult> { 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<CreateJoinRoomResult>; } export const createRoom: CreateRoomOnMediaSFUType = ({ payload }) => postRoom('/api/mediasfu/create-room', payload); export const joinRoom: JoinRoomOnMediaSFUType = ({ payload }) => postRoom('/api/mediasfu/join-room', payload);
src/App.vue
<script setup lang="ts">import { MediasfuGeneric } from 'mediasfu-vue'; import 'mediasfu-vue/dist/mediasfu-vue.css'; import { createRoom, joinRoom } from './room-gateway';</script>
<template><main><h1>Classroom workshop</h1><p>Open Messages, Polls, Breakouts, or Whiteboard.</p><MediasfuGeneric :return-u-i="true" :connect-media-s-f-u="true" :create-media-s-f-u-room="createRoom" :join-media-s-f-u-room="joinRoom" /></main></template>
src/main.ts
import { createApp } from 'vue'; import App from './App.vue'; createApp(App).mount('#app');
index.html
<!doctype html><html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width,initial-scale=1" /><title>Classroom</title></head><body><div id="app"></div><script type="module" src="/src/main.ts"></script></body></html>
vite.config.ts
import { defineConfig } from 'vite'; import vue from '@vitejs/plugin-vue'; export default defineConfig({ plugins: [vue()] });
tsconfig.json
{"compilerOptions":{"target":"ES2022","lib":["DOM","ES2022"],"strict":true,"module":"ESNext","moduleResolution":"Bundler","skipLibCheck":true,"noEmit":true},"include":["src"]}

Use restricted, revocable, uncommitted credentials only on an isolated local backend. Before distribution, external testing, or production, reusable Cloud credentials remain only on the authenticated backend.

Backend

Keep src/room-gateway.ts in this project and implement its two API routes using the complete public production room credential boundary. The backend authorizes teacher and learner roles; the browser never receives a Cloud credential.

Run

npm install
npm run dev

Expected result

Teacher and learner exchange a message, complete a poll, enter/leave a breakout, and open/close the whiteboard according to room permissions.

Recovery

If a breakout move fails, keep the learner in the main room. Refresh current room state before retrying interrupted poll or whiteboard actions.

Cleanup

End polls and breakouts, close the whiteboard, clear app-owned drafts, use Leave, and expire backend room authority.