← Back to the library
Collaboration and knowledge

Zoom Meeting SDK Web Client View

Zoom Meeting SDK Web - Client View. Full-page Zoom meeting experience with the familiar Zoom interface. Uses ZoomMtg global singleton with callback-based API. Ideal for quick integration with minimal customization. Provides the same UI as Zoom Web Client.

OpenAI pluginVersion 1.0.0Exact read-only source

Zoom Meeting SDK Web - Client View

Full-page Zoom meeting experience embedded in your web application. Client View provides the familiar Zoom interface with minimal customization needed.

Overview

Client View uses the `ZoomMtg` global singleton to render a full-page meeting experience identical to the Zoom Web Client.

| Aspect | Details | |--------|---------| | **API Object** | `ZoomMtg` (global singleton) | | **API Style** | Callback-based | | **UI** | Full-page takeover | | **Password param** | `passWord` (capital W) | | **Events** | `inMeetingServiceListener()` | | **Best For** | Quick integration, standard Zoom UI |

Installation

NPM

```bash npm install @zoom/meetingsdk --save ```

```javascript import { ZoomMtg } from '@zoom/meetingsdk'; ```

CDN

```html <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

```javascript // 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

| Parameter | Type | Description | |-----------|------|-------------| | `leaveUrl` | `string` | URL to redirect after leaving meeting |

UI Customization

| Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `showMeetingHeader` | `boolean` | `true` | Show meeting number and topic | | `disableInvite` | `boolean` | `false` | Hide invite button | | `disableCallOut` | `boolean` | `false` | Hide call out option | | `disableRecord` | `boolean` | `false` | Hide record button | | `disableJoinAudio` | `boolean` | `false` | Hide join audio option | | `disablePreview` | `boolean` | `false` | Skip audio/video preview | | `audioPanelAlwaysOpen` | `boolean` | `false` | Keep audio panel open | | `showPureSharingContent` | `boolean` | `false` | Prevent overlays on shared content | | `videoHeader` | `boolean` | `true` | Show video tile header | | `isLockBottom` | `boolean` | `true` | Show/hide footer | | `videoDrag` | `boolean` | `true` | Enable drag video tiles | | `sharingMode` | `string` | `'both'` | `'both'` or `'fit'` | | `screenShare` | `boolean` | `true` | Enable browser URL sharing | | `hideShareAudioOption` | `boolean` | `false` | Hide "Share tab audio" checkbox | | `disablePictureInPicture` | `boolean` | `false` | Disable PiP mode | | `disableZoomLogo` | `boolean` | `false` | Remove Zoom logo (deprecated) | | `defaultView` | `string` | `'speaker'` | `'gallery'`, `'speaker'`, `'multiSpeaker'` |

Feature Toggles

| Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `isSupportAV` | `boolean` | `true` | Enable audio/video | | `isSupportChat` | `boolean` | `true` | Enable in-meeting chat | | `isSupportQA` | `boolean` | `true` | Enable webinar Q&A | | `isSupportCC` | `boolean` | `true` | Enable closed captions | | `isSupportPolling` | `boolean` | `true` | Enable polling | | `isSupportBreakout` | `boolean` | `true` | Enable breakout rooms | | `isSupportNonverbal` | `boolean` | `true` | Enable nonverbal feedback | | `isSupportSimulive` | `boolean` | `false` | Enable Simulive | | `disableVoIP` | `boolean` | `false` | Disable VoIP | | `disableReport` | `boolean` | `false` | Disable report feature |

Video Quality

| Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `enableHD` | `boolean` | `true` (≥2.8.0) | Enable 720p video | | `enableFullHD` | `boolean` | `false` | Enable 1080p for webinar attendees |

Advanced

| Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `debug` | `boolean` | `false` | Enable debug logging | | `patchJsMedia` | `boolean` | `false` | Auto-apply media fixes | | `disableCORP` | `boolean` | `false` | Disable web isolation | | `helper` | `string` | `''` | Path to helper.html | | `externalLinkPage` | `string` | - | Page for external links | | `webEndpoint` | `string` | - | For ZFG environments | | `leaveOnPageUnload` | `boolean` | `false` | Auto cleanup on page close | | `isShowJoiningErrorDialog` | `boolean` | `true` | Show error dialog on join failure | | `meetingInfo` | `Array<string>` | `[...]` | Meeting info to display | | `inviteUrlFormat` | `string` | `''` | Custom invite URL format | | `loginWindow` | `object` | `{width: 400, height: 380}` | Login popup size |

Callbacks

| Parameter | Type | Description | |-----------|------|-------------| | `success` | `Function` | Called on successful init | | `error` | `Function` | Called on init failure |

ZoomMtg.join() - All Options

Required

| Parameter | Type | Description | |-----------|------|-------------| | `signature` | `string` | SDK JWT from backend (v5.0+: must include appKey prefix) | | `meetingNumber` | `string \| number` | Meeting or webinar number | | `userName` | `string` | Display name | | `passWord` | `string` | Meeting password (capital W!) |

Authentication

| Parameter | Type | When Required | Description | |-----------|------|---------------|-------------| | `zak` | `string` | Starting as host | Host's Zoom Access Key | | `tk` | `string` | Registration required | Registrant token | | `userEmail` | `string` | Webinars | User email | | `obfToken` | `string` | March 2026+ | App Privilege Token |

Optional

| Parameter | Type | Description | |-----------|------|-------------| | `customerKey` | `string` | Custom ID (max 36 chars) | | `recordingToken` | `string` | Local recording permission |

Callbacks

| Parameter | Type | Description | |-----------|------|-------------| | `success` | `Function` | Called on successful join | | `error` | `Function` | Called on join failure |

Event Listeners

User Events

```javascript ZoomMtg.inMeetingServiceListener('onUserJoin', (data) => { console.log('User joined:', data); // { userId, userName, ... } });

ZoomMtg.inMeetingServiceListener('onUserLeave', (data) => { console.log('User left:', data); // Reason codes: // 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

```javascript ZoomMtg.inMeetingServiceListener('onMeetingStatus', (data) => { // status: 1=connecting, 2=connected, 3=disconnected, 4=reconnecting console.log('Status:', data.status); }); ```

Audio/Video Events

```javascript 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

```javascript 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

```javascript 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

```javascript ZoomMtg.inMeetingServiceListener('onRoomStatusChange', (data) => { // status: 2=InProgress, 3=Closing, 4=Closed console.log('Breakout room status:', data); }); ```

Other Events

```javascript 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

```javascript // 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

```javascript // 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

```javascript // Send chat message ZoomMtg.sendChat({ message: 'Hello!', userId: 0 // 0 = everyone }); ```

Meeting Control

```javascript // Leave meeting ZoomMtg.leaveMeeting({});

// End meeting (host only) ZoomMtg.endMeeting({});

// Lock meeting ZoomMtg.lockMeeting({ lock: true }); ```

Host Controls

```javascript // 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

```javascript // Raise hand ZoomMtg.raiseHand({ userId });

// Lower hand ZoomMtg.lowerHand({ oderId });

// Lower all hands ZoomMtg.lowerAllHands({}); ```

Spotlight & Pin

```javascript // Spotlight video ZoomMtg.operateSpotlight({ oderId, action: 'add' }); // or 'remove'

// Pin video ZoomMtg.operatePin({ oderId, action: 'add' }); // or 'remove'

// Allow multi-pin ZoomMtg.allowMultiPin({ allow: true }); ```

Screen Share

```javascript // Start screen share ZoomMtg.startScreenShare({});

// Share specific source (Electron) ZoomMtg.shareSource({ source }); ```

Recording

```javascript // Start/stop recording ZoomMtg.record({ record: true }); // or false

// Show/hide record button ZoomMtg.showRecordFunction({ show: true }); ```

Breakout Rooms

```javascript // 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

```javascript // 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

```javascript // 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

```javascript // 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

| Method | Limit | |--------|-------| | `join()` | 10 seconds | | `callOut()` | 10 seconds | | `mute()` | 1 second | | `muteAll()` | 5 seconds |

DOM Elements

The SDK automatically adds these elements: - `#zmmtg-root` - Main meeting container - `#aria-notify-area` - Accessibility announcements

Do NOT manually create or remove these.

SPA (React/Next) Overlay Gotcha

If you "join" but see a blank/black area or your app shell instead of the meeting UI, the Zoom UI can be rendering **behind** your app layout. Ensure `#zmmtg-root` occupies the viewport and is above other fixed elements:

```css #zmmtg-root { position: fixed !important; inset: 0 !important; z-index: 9999 !important; } ```

Join Payload Sanitization Gotcha

If `ZoomMtg.join()` succeeds partially but the screen turns black and console shows errors like `Cannot read properties of undefined (reading 'toString')`, sanitize optional fields before calling join.

Do not pass optional keys with `undefined` values (`userEmail`, `tk`, `zak`, etc.). Build a payload and only attach those keys when they are non-empty strings.

Also prefer `defaultView: 'speaker'` during `ZoomMtg.init()` unless you have SharedArrayBuffer/gallery-view prerequisites fully configured.

Resources

  • [Main Web SDK Skill](../SKILL.md)
  • [Reference Index](references/index.md)
  • [Error Codes](../troubleshooting/error-codes.md)
  • [Common Issues](../troubleshooting/common-issues.md)
  • [SharedArrayBuffer Setup](../concepts/sharedarraybuffer.md)
  • [Official API Reference](https://marketplacefront.zoom.us/sdk/meeting/web/index.html)

Operations

  • [RUNBOOK.md](RUNBOOK.md) - 5-minute preflight and debugging checklist.