Zoom Meeting SDK Web - Client View
Expérience de réunion Zoom sur toute la page intégrée dans votre application web. Client View offre l'interface Zoom familière avec un besoin minimal de personnalisation.
Overview
Client View utilise le singleton global ZoomMtg pour afficher une expérience de réunion sur toute la page, identique au client Web Zoom.
| Aspect |
Détails |
| Objet API |
ZoomMtg (singleton global) |
| Style API |
Basé sur les callbacks |
| Interface |
Prise de contrôle de la page entière |
| Paramètre de mot de passe |
passWord (W majuscule) |
| Événements |
inMeetingServiceListener() |
| Idéal pour |
Intégration rapide, interface Zoom standard |
Installation
NPM
npm install @zoom/meetingsdk --save
import { ZoomMtg } from '@zoom/meetingsdk';
CDN
<script src="https://source.zoom.us/{VERSION}/lib/vendor/react.min.js"></script>
<script src="https://source.zoom.us/{VERSION}/lib/vendor/react-dom.min.js"></script>
<script src="https://source.zoom.us/{VERSION}/lib/vendor/redux.min.js"></script>
<script src="https://source.zoom.us/{VERSION}/lib/vendor/redux-thunk.min.js"></script>
<script src="https://source.zoom.us/{VERSION}/lib/vendor/lodash.min.js"></script>
<script src="https://source.zoom.us/zoom-meeting-{VERSION}.min.js"></script>
Complete Initialization Flow
// Step 1: Check browser compatibility
console.log('Requirements:', ZoomMtg.checkSystemRequirements());
// Step 2: Set CDN path (optional - for China or custom hosting)
// ZoomMtg.setZoomJSLib('https://source.zoom.us/{VERSION}/lib', '/av');
// Step 3: Preload WebAssembly modules
ZoomMtg.preLoadWasm();
ZoomMtg.prepareWebSDK();
// Step 4: Load language resources
ZoomMtg.i18n.load('en-US');
ZoomMtg.i18n.onLoad(() => {
// Step 5: Initialize SDK
ZoomMtg.init({
leaveUrl: '/meeting-ended',
patchJsMedia: true,
disableCORP: !window.crossOriginIsolated,
success: () => {
console.log('SDK initialized');
// Step 6: Join meeting
const joinPayload = {
signature: signature,
meetingNumber: meetingNumber,
userName: userName,
passWord: passWord,
success: (res) => {
console.log('Joined meeting');
// Step 7: Post-join operations
ZoomMtg.getAttendeeslist({});
ZoomMtg.getCurrentUser({
success: (res) => console.log('Current user:', res.result.currentUser)
});
},
error: (err) => console.error('Join failed:', err)
};
// IMPORTANT: only include optional fields when they have real values
// Passing undefined for some optional fields can cause runtime join errors
if (userEmail) joinPayload.userEmail = userEmail;
if (tk) joinPayload.tk = tk;
if (zak) joinPayload.zak = zak;
ZoomMtg.join(joinPayload);
},
error: (err) => console.error('Init failed:', err)
});
});
ZoomMtg.init() - All Options
Required
| Paramètre |
Type |
Description |
leaveUrl |
string |
URL de redirection après avoir quitté la réunion |
UI Customization
| Paramètre |
Type |
Défaut |
Description |
showMeetingHeader |
boolean |
true |
Afficher le numéro de réunion et le sujet |
disableInvite |
boolean |
false |
Masquer le bouton d'invitation |
disableCallOut |
boolean |
false |
Masquer l'option d'appel sortant |
disableRecord |
boolean |
false |
Masquer le bouton d'enregistrement |
disableJoinAudio |
boolean |
false |
Masquer l'option de participation audio |
disablePreview |
boolean |
false |
Ignorer l'aperçu audio/vidéo |
audioPanelAlwaysOpen |
boolean |
false |
Garder le panneau audio ouvert |
showPureSharingContent |
boolean |
false |
Empêcher les superpositions sur le contenu partagé |
videoHeader |
boolean |
true |
Afficher l'en-tête de la tuile vidéo |
isLockBottom |
boolean |
true |
Afficher/masquer le pied de page |
videoDrag |
boolean |
true |
Activer le glissement des tuiles vidéo |
sharingMode |
string |
'both' |
'both' ou 'fit' |
screenShare |
boolean |
true |
Activer le partage d'URL du navigateur |
hideShareAudioOption |
boolean |
false |
Masquer la case à cocher « Partager l'audio de l'onglet » |
disablePictureInPicture |
boolean |
false |
Désactiver le mode PiP |
disableZoomLogo |
boolean |
false |
Supprimer le logo Zoom (obsolète) |
defaultView |
string |
'speaker' |
'gallery', 'speaker', 'multiSpeaker' |
Feature Toggles
| Paramètre |
Type |
Défaut |
Description |
isSupportAV |
boolean |
true |
Activer l'audio/vidéo |
isSupportChat |
boolean |
true |
Activer le chat en réunion |
isSupportQA |
boolean |
true |
Activer Q&A pour webinaire |
isSupportCC |
boolean |
true |
Activer les sous-titres |
isSupportPolling |
boolean |
true |
Activer les sondages |
isSupportBreakout |
boolean |
true |
Activer les salles de débat |
isSupportNonverbal |
boolean |
true |
Activer les retours non verbaux |
isSupportSimulive |
boolean |
false |
Activer Simulive |
disableVoIP |
boolean |
false |
Désactiver VoIP |
disableReport |
boolean |
false |
Désactiver la fonction de signalement |
Video Quality
| Paramètre |
Type |
Défaut |
Description |
enableHD |
boolean |
true (≥2.8.0) |
Activer la vidéo 720p |
enableFullHD |
boolean |
false |
Activer la 1080p pour les participants au webinaire |
Advanced
| Paramètre |
Type |
Défaut |
Description |
debug |
boolean |
false |
Activer la journalisation de débogage |
patchJsMedia |
boolean |
false |
Appliquer automatiquement les correctifs médias |
disableCORP |
boolean |
false |
Désactiver l'isolation Web |
helper |
string |
'' |
Chemin vers helper.html |
externalLinkPage |
string |
- |
Page pour les liens externes |
webEndpoint |
string |
- |
Pour les environnements ZFG |
leaveOnPageUnload |
boolean |
false |
Nettoyage automatique lors de la fermeture de la page |
isShowJoiningErrorDialog |
boolean |
true |
Afficher le dialogue d'erreur en cas d'échec de connexion |
meetingInfo |
Array<string> |
[...] |
Informations de réunion à afficher |
inviteUrlFormat |
string |
'' |
Format d'URL d'invitation personnalisé |
loginWindow |
object |
{width: 400, height: 380} |
Taille de la fenêtre de connexion |
Callbacks
| Paramètre |
Type |
Description |
success |
Function |
Appelé lors de l'initialisation réussie |
error |
Function |
Appelé en cas d'échec de l'initialisation |
ZoomMtg.join() - All Options
Required
| Paramètre |
Type |
Description |
signature |
string |
SDK JWT du backend (v5.0+ : doit inclure le préfixe appKey) |
meetingNumber |
string \| number |
Numéro de réunion ou de webinaire |
userName |
string |
Nom d'affichage |
passWord |
string |
Mot de passe de la réunion (W majuscule !) |
Authentication
| Paramètre |
Type |
Quand requis |
Description |
zak |
string |
Au démarrage en tant qu'hôte |
Clé d'accès Zoom de l'hôte |
tk |
string |
Inscription requise |
Jeton du participant inscrit |
userEmail |
string |
Webinaires |
Email de l'utilisateur |
obfToken |
string |
Mars 2026+ |
Jeton de privilège d'application |
Optional
| Paramètre |
Type |
Description |
customerKey |
string |
ID personnalisé (max 36 caractères) |
recordingToken |
string |
Permission d'enregistrement local |
Callbacks
| Paramètre |
Type |
Description |
success |
Function |
Appelé lors de la connexion réussie |
error |
Function |
Appelé en cas d'échec de la connexion |
Event Listeners
User Events
ZoomMtg.inMeetingServiceListener('onUserJoin', (data) => {
console.log('User joined:', data);
// { userId, userName, ... }
});
ZoomMtg.inMeetingServiceListener('onUserLeave', (data) => {
console.log('User left:', data);
// Codes de raison :
// 0: OTHER
// 1: HOST_ENDED_MEETING
// 2: SELF_LEAVE_FROM_IN_MEETING
// 3: SELF_LEAVE_FROM_WAITING_ROOM
// 4: SELF_LEAVE_FROM_WAITING_FOR_HOST_START
// 5: MEETING_TRANSFER
// 6: KICK_OUT_FROM_MEETING
// 7: KICK_OUT_FROM_WAITING_ROOM
// 8: LEAVE_FROM_DISCLAIMER
});
ZoomMtg.inMeetingServiceListener('onUserUpdate', (data) => {
console.log('User updated:', data);
});
ZoomMtg.inMeetingServiceListener('onUserIsInWaitingRoom', (data) => {
console.log('User in waiting room:', data);
});
Meeting Status
ZoomMtg.inMeetingServiceListener('onMeetingStatus', (data) => {
// status: 1=connecting, 2=connected, 3=disconnected, 4=reconnecting
console.log('Status:', data.status);
});
Audio/Video Events
ZoomMtg.inMeetingServiceListener('onActiveSpeaker', (data) => {
// [{userId, userName}]
console.log('Active speaker:', data);
});
ZoomMtg.inMeetingServiceListener('onNetworkQualityChange', (data) => {
// {level: 0-5, userId, type: 'uplink'}
// 0-1=bad, 2=normal, 3-5=good
console.log('Network quality:', data);
});
ZoomMtg.inMeetingServiceListener('onAudioQos', (data) => {
console.log('Audio QoS:', data);
});
ZoomMtg.inMeetingServiceListener('onVideoQos', (data) => {
console.log('Video QoS:', data);
});
Chat & Communication
ZoomMtg.inMeetingServiceListener('onReceiveChatMsg', (data) => {
console.log('Chat message:', data);
});
ZoomMtg.inMeetingServiceListener('onReceiveTranscriptionMsg', (data) => {
console.log('Transcription:', data);
});
ZoomMtg.inMeetingServiceListener('onReceiveTranslateMsg', (data) => {
console.log('Translation:', data);
});
Recording & Sharing
ZoomMtg.inMeetingServiceListener('onRecordingChange', (data) => {
console.log('Recording status:', data);
});
ZoomMtg.inMeetingServiceListener('onShareContentChange', (data) => {
console.log('Share content:', data);
});
ZoomMtg.inMeetingServiceListener('receiveSharingChannelReady', (data) => {
console.log('Sharing channel ready:', data);
});
Breakout Rooms
ZoomMtg.inMeetingServiceListener('onRoomStatusChange', (data) => {
// status: 2=InProgress, 3=Closing, 4=Closed
console.log('Breakout room status:', data);
});
Other Events
ZoomMtg.inMeetingServiceListener('onJoinSpeed', (data) => {
console.log('Join metrics:', data);
});
ZoomMtg.inMeetingServiceListener('onVbStatusChange', (data) => {
console.log('Virtual background status:', data);
});
ZoomMtg.inMeetingServiceListener('onFocusModeStatusChange', (data) => {
console.log('Focus mode:', data);
});
ZoomMtg.inMeetingServiceListener('onPictureInPicture', (data) => {
console.log('PiP status:', data);
});
ZoomMtg.inMeetingServiceListener('onClaimStatus', (data) => {
console.log('Host claim status:', data);
});
Common Methods
Meeting Info
// Get current user
ZoomMtg.getCurrentUser({
success: (res) => console.log(res.result.currentUser)
});
// Get all attendees
ZoomMtg.getAttendeeslist({});
// Get meeting info
ZoomMtg.getCurrentMeetingInfo({
success: (res) => console.log(res)
});
// Get SDK version
ZoomMtg.getWebSDKVersion({
success: (version) => console.log(version)
});
Audio/Video Control
// Mute/unmute specific user
ZoomMtg.mute({ userId, mute: true });
// Mute/unmute all
ZoomMtg.muteAll({ muteAll: true });
// Stop incoming audio
ZoomMtg.stopIncomingAudio({ stop: true });
// Mirror video
ZoomMtg.mirrorVideo({ mirror: true });
Chat
// Send chat message
ZoomMtg.sendChat({
message: 'Hello!',
userId: 0 // 0 = everyone
});
Meeting Control
// Leave meeting
ZoomMtg.leaveMeeting({});
// End meeting (host only)
ZoomMtg.endMeeting({});
// Lock meeting
ZoomMtg.lockMeeting({ lock: true });
Host Controls
// Make host
ZoomMtg.makeHost({ userId });
// Make co-host
ZoomMtg.makeCoHost({ userId });
// Remove co-host
ZoomMtg.withdrawCoHost({ userId });
// Remove participant
ZoomMtg.expel({ userId });
// Put on hold
ZoomMtg.putOnHold({ userId, bHold: true });
// Claim host with host key
ZoomMtg.claimHostWithHostKey({ hostKey: '123456' });
// Reclaim host
ZoomMtg.reclaimHost({});
// Admit all from waiting room
ZoomMtg.admitAll({});
Raise Hand
// Raise hand
ZoomMtg.raiseHand({ userId });
// Lower hand
ZoomMtg.lowerHand({ oderId });
// Lower all hands
ZoomMtg.lowerAllHands({});
Spotlight & Pin
// Spotlight video
ZoomMtg.operateSpotlight({ oderId, action: 'add' }); // ou 'remove'
// Pin video
ZoomMtg.operatePin({ oderId, action: 'add' }); // ou 'remove'
// Allow multi-pin
ZoomMtg.allowMultiPin({ allow: true });
Screen Share
// Start screen share
ZoomMtg.startScreenShare({});
// Share specific source (Electron)
ZoomMtg.shareSource({ source });
Recording
// Start/stop recording
ZoomMtg.record({ record: true }); // ou false
// Show/hide record button
ZoomMtg.showRecordFunction({ show: true });
Breakout Rooms
// Create breakout room
ZoomMtg.createBreakoutRoom({
rooms: [{ name: 'Room 1' }, { name: 'Room 2' }]
});
// Open breakout rooms
ZoomMtg.openBreakoutRooms({});
// Close breakout rooms
ZoomMtg.closeBreakoutRooms({});
// Join breakout room
ZoomMtg.joinBreakoutRoom({ roomId });
// Leave breakout room
ZoomMtg.leaveBreakoutRoom({});
// Move user to breakout room
ZoomMtg.moveUserToBreakoutRoom({ oderId, roomId });
// Get breakout room status
ZoomMtg.getBreakoutRoomStatus({
success: (res) => console.log(res)
});
Virtual Background
// Check support
ZoomMtg.isSupportVirtualBackground({
success: (data) => console.log(data.result.isSupport)
});
// Set virtual background
ZoomMtg.setVirtualBackground({ imageUrl: '...' });
// Get VB status
ZoomMtg.getVirtualBackgroundStatus({
success: (data) => console.log(data)
});
// Lock virtual background (host)
ZoomMtg.lockVirtualBackground({ lock: true });
UI Control
// Show/hide meeting header
ZoomMtg.showMeetingHeader({ show: true });
// Show/hide invite button
ZoomMtg.showInviteFunction({ show: true });
// Show/hide join audio button
ZoomMtg.showJoinAudioFunction({ show: true });
// Show/hide callout button
ZoomMtg.showCalloutFunction({ show: true });
// Re-render with new options
ZoomMtg.reRender({ lang: 'de-DE' });
Language
// Load language
ZoomMtg.i18n.load('de-DE');
// Reload language
ZoomMtg.i18n.reload('de-DE');
// Get current language
ZoomMtg.i18n.getCurrentLang();
// Get all translations
ZoomMtg.i18n.getAll();
Rate Limits
| Méthode |
Limite |
join() |
10 secondes |
callOut() |
10 secondes |
mute() |
1 seconde |
muteAll() |
5 secondes |
DOM Elements
Le SDK ajoute automatiquement ces éléments :
#zmmtg-root - Conteneur de réunion principal
#aria-notify-area - Annonces d'accessibilité
NE les créez PAS ou NE les supprimez PAS manuellement.
SPA (React/Next) Overlay Gotcha
Si vous « rejoignez » mais voyez une zone vide/noire ou l'interface de votre application à la place de l'interface de réunion, l'interface Zoom peut s'afficher derrière votre disposition d'application. Assurez-vous que #zmmtg-root occupe la fenêtre d'affichage et se trouve au-dessus des autres éléments fixes :
#zmmtg-root {
position: fixed !important;
inset: 0 !important;
z-index: 9999 !important;
}
Join Payload Sanitization Gotcha
Si ZoomMtg.join() réussit partiellement mais l'écran devient noir et la console affiche des erreurs comme Cannot read properties of undefined (reading 'toString'), nettoyez les champs optionnels avant d'appeler join.
Ne passez pas de clés optionnelles avec des valeurs undefined (userEmail, tk, zak, etc.). Construisez un payload et attachez uniquement ces clés quand elles contiennent des chaînes non vides.
Préférez également defaultView: 'speaker' lors de ZoomMtg.init() sauf si vous avez complètement configuré les prérequis SharedArrayBuffer/gallery-view.
Resources
Operations
- RUNBOOK.md - Checklist de préflight et de débogage de 5 minutes.