Knowledge-work-plugins zoom-meeting-sdk-web
git clone https://github.com/anthropics/knowledge-work-plugins
T=$(mktemp -d) && git clone --depth=1 https://github.com/anthropics/knowledge-work-plugins "$T" && mkdir -p ~/.claude/skills && cp -r "$T/partner-built/zoom-plugin/skills/meeting-sdk/web" ~/.claude/skills/anthropics-knowledge-work-plugins-zoom-meeting-sdk-web && rm -rf "$T"
partner-built/zoom-plugin/skills/meeting-sdk/web/SKILL.mdZoom Meeting SDK (Web)
Embed Zoom meeting capabilities into web applications with two integration options: Client View (full-page) or Component View (embeddable).
How to Implement a Custom Video User Interface for a Zoom Meeting in a Web App
Use Meeting SDK Web Component View.
Do not use Video SDK for this question unless the user is explicitly building a non-meeting session product.
Minimal architecture:
Browser page -> fetch Meeting SDK signature from backend -> ZoomMtgEmbedded.createClient() -> client.init({ zoomAppRoot }) -> client.join({ signature, sdkKey, meetingNumber, userName, password }) -> apply layout/style/customize options around the embedded meeting container
Minimal implementation:
import ZoomMtgEmbedded from '@zoom/meetingsdk/embedded'; const client = ZoomMtgEmbedded.createClient(); export async function startEmbeddedMeeting(meetingNumber: string, userName: string, password: string) { const sigRes = await fetch('/api/signature', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ meetingNumber, role: 0 }), }); if (!sigRes.ok) throw new Error(`signature_fetch_failed:${sigRes.status}`); const { signature, sdkKey } = await sigRes.json(); await client.init({ zoomAppRoot: document.getElementById('meetingSDKElement')!, language: 'en-US', patchJsMedia: true, leaveOnPageUnload: true, customize: { video: { isResizable: true, popper: { disableDraggable: false } }, }, }); await client.join({ signature, sdkKey, meetingNumber, userName, password, }); }
Common failure points:
- wrong route: Video SDK instead of Meeting SDK Component View
- missing backend signature endpoint
- wrong password field (
here, notpassword
)passWord - missing OBF/ZAK requirements for meetings outside the app account
- missing SharedArrayBuffer headers when higher-end meeting features are expected
Hard Routing Rule
If the user wants a custom video user interface for a Zoom meeting in a web app, route to Component View, not Video SDK.
- Meeting SDK Component View = custom UI for a real Zoom meeting
- Video SDK Web = custom UI for a non-meeting video session product
For the direct custom-meeting-UI path, start with component-view/SKILL.md.
New to Web SDK? Start Here!
The fastest way to master the SDK:
- Choose Your View - Client View vs Component View - Understand the key architectural differences
- Quick Start - Client View or Component View - Get a working meeting in minutes
- SharedArrayBuffer - concepts/sharedarraybuffer.md - Required for HD video, gallery view, virtual backgrounds
- Optional preflight diagnostics - ../../probe-sdk/SKILL.md - Validate browser/device/network before join
Building a Custom Integration?
- Component View gives you Promise-based API and embeddable UI
- Client View gives you the familiar full-page Zoom experience
- For a custom meeting UI, prefer Component View first
- Cross-product routing example: ../../general/use-cases/custom-meeting-ui-web.md
- Browser Support - Feature matrix by browser
- Exact deep-dive path: component-view/SKILL.md
Having issues?
- Join errors → Check signature generation and password spelling (
vspassWord
)password - HD video not working → Enable SharedArrayBuffer headers
- Complete navigation → SKILL.md
Prerequisites
- Zoom app with Meeting SDK credentials from Marketplace
- SDK Key (Client ID) and Secret
- Modern browser (Chrome, Firefox, Safari, Edge)
- Backend auth endpoint for signature generation
Need help with authentication? See the zoom-oauth skill for JWT/signature generation.
Want pre-join diagnostics? Chain probe-sdk before
/init()to gate low-readiness environments.join()
Optional Preflight Gate (Probe SDK)
For unstable first-join environments, run Probe SDK checks before calling
ZoomMtg.init() or client.join():
- Run Probe permissions/device/network diagnostics.
- Apply readiness policy (
,allow
,warn
).block - Continue to Meeting SDK join only for
/approvedallow
.warn
See ../../probe-sdk/SKILL.md and ../../general/use-cases/probe-sdk-preflight-readiness-gate.md.
Client View vs Component View
CRITICAL DIFFERENCE: These are two completely different APIs with different patterns!
| Aspect | Client View | Component View |
|---|---|---|
| Object | (global singleton) | (instance) |
| API Style | Callbacks | Promises |
| UI | Full-page takeover | Embeddable in any container |
| Password param | (capital W) | (lowercase) |
| Events | | / |
| Import (npm) | | |
| CDN | | |
| Best For | Quick integration, standard Zoom UI | Custom layouts, React/Vue apps |
When to Use Which
Use Client View when:
- You want the familiar Zoom meeting interface
- Quick integration is priority over customization
- Full-page meeting experience is acceptable
Use Component View when:
- You need to embed meetings in a specific area of your page
- Building React/Vue/Angular applications
- You want Promise-based async/await syntax
- Custom positioning and resizing is required
Installation
NPM (Recommended)
npm install @zoom/meetingsdk --save
CDN
<!-- Dependencies (required for both views) --> <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> <!-- Client View --> <script src="https://source.zoom.us/zoom-meeting-{VERSION}.min.js"></script> <!-- OR Component View --> <script src="https://source.zoom.us/zoom-meeting-embedded-{VERSION}.min.js"></script>
Replace
{VERSION} with the latest version (e.g., 3.11.0).
Quick Start (Client View)
import { ZoomMtg } from '@zoom/meetingsdk'; // Step 1: Check browser compatibility console.log('System requirements:', ZoomMtg.checkSystemRequirements()); // Step 2: Preload WebAssembly for faster initialization ZoomMtg.preLoadWasm(); ZoomMtg.prepareWebSDK(); // Step 3: Load language files (MUST complete before init) ZoomMtg.i18n.load('en-US'); ZoomMtg.i18n.onLoad(() => { // Step 4: Initialize SDK ZoomMtg.init({ leaveUrl: 'https://yoursite.com/meeting-ended', disableCORP: !window.crossOriginIsolated, // Auto-detect SharedArrayBuffer patchJsMedia: true, // Auto-apply media dependency fixes leaveOnPageUnload: true, // Clean up when page unloads externalLinkPage: './external.html', // Page for external links success: () => { // Step 5: Join meeting (note: passWord with capital W!) ZoomMtg.join({ signature: signature, // From your auth endpoint meetingNumber: '1234567890', userName: 'User Name', passWord: 'meeting-password', // Capital W! success: (res) => { console.log('Joined meeting:', res); // Post-join: Get meeting info ZoomMtg.getAttendeeslist({}); ZoomMtg.getCurrentUser({ success: (res) => console.log('Current user:', res.result.currentUser) }); }, error: (err) => { console.error('Join error:', err); } }); }, error: (err) => { console.error('Init error:', err); } }); });
Quick Start (Component View)
import ZoomMtgEmbedded from '@zoom/meetingsdk/embedded'; // Create client instance (do this ONCE, not on every render!) const client = ZoomMtgEmbedded.createClient(); async function startMeeting() { try { // Initialize with container element await client.init({ zoomAppRoot: document.getElementById('meetingSDKElement'), language: 'en-US', debug: true, // Enable debug logging patchJsMedia: true, // Auto-apply media fixes leaveOnPageUnload: true, // Clean up on page unload }); // Join meeting (note: password lowercase!) await client.join({ signature: signature, // From your auth endpoint sdkKey: SDK_KEY, meetingNumber: '1234567890', userName: 'User Name', password: 'meeting-password', // Lowercase! }); console.log('Joined successfully!'); } catch (error) { console.error('Failed to join:', error); } }
Authentication Endpoint (Required)
Both views require a JWT signature from a backend server. Never expose your SDK Secret in frontend code!
# Clone Zoom's official auth endpoint git clone https://github.com/zoom/meetingsdk-auth-endpoint-sample --depth 1 cd meetingsdk-auth-endpoint-sample cp .env.example .env # Edit .env with your SDK Key and Secret npm install && npm run start
Signature Generation
The signature encodes:
(orsdkKey
for newer apps)clientIdmeetingNumber
(0 = participant, 1 = host)role
(issued at timestamp)iat
(expiration timestamp)exp
(token expiration)tokenExp
IMPORTANT (March 2026): Apps joining meetings outside their account will require an App Privilege Token (OBF) or ZAK token. See Authorization Requirements.
Core Workflow
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ Get Signature │───►│ init() │───►│ join() │ │ (from backend)│ │ (SDK setup) │ │ (enter mtg) │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ │ ▼ ▼ success/error success/error callback callback (or Promise resolve) (or Promise resolve)
Client View API Reference
ZoomMtg.init() - Key Options
ZoomMtg.init({ // Required leaveUrl: string, // URL to redirect after leaving // Display Options showMeetingHeader: boolean, // Show meeting number/topic (default: true) disableInvite: boolean, // Hide invite button (default: false) disableRecord: boolean, // Hide record button (default: false) disableJoinAudio: boolean, // Hide join audio option (default: false) disablePreview: boolean, // Skip A/V preview (default: false) // HD Video (requires SharedArrayBuffer) enableHD: boolean, // Enable 720p (default: true for >=2.8.0) enableFullHD: boolean, // Enable 1080p for webinars (default: false) // View Options defaultView: 'gallery' | 'speaker' | 'multiSpeaker', // Feature Toggles isSupportChat: boolean, // Enable chat (default: true) isSupportCC: boolean, // Enable closed captions (default: true) isSupportBreakout: boolean, // Enable breakout rooms (default: true) isSupportPolling: boolean, // Enable polling (default: true) isSupportQA: boolean, // Enable Q&A for webinars (default: true) // Cross-Origin disableCORP: boolean, // For dev without COOP/COEP headers // Callbacks success: Function, error: Function, });
ZoomMtg.join() - Key Options
ZoomMtg.join({ // Required signature: string, // JWT signature from backend meetingNumber: string | number, userName: string, // Authentication passWord: string, // Meeting password (capital W!) zak: string, // Host's ZAK token (required to start) tk: string, // Registration token (if required) obfToken: string, // App Privilege Token (for 2026 requirement) // Optional userEmail: string, // Required for webinars customerKey: string, // Custom identifier (max 36 chars) // Callbacks success: Function, error: Function, });
Event Listeners (Client View)
// User events ZoomMtg.inMeetingServiceListener('onUserJoin', (data) => { console.log('User joined:', data); }); ZoomMtg.inMeetingServiceListener('onUserLeave', (data) => { console.log('User left:', data); // data.reasonCode values: // 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); }); // Meeting status ZoomMtg.inMeetingServiceListener('onMeetingStatus', (data) => { // status: 1=connecting, 2=connected, 3=disconnected, 4=reconnecting console.log('Meeting status:', data.status); }); // Waiting room ZoomMtg.inMeetingServiceListener('onUserIsInWaitingRoom', (data) => { console.log('User in waiting room:', data); }); // Active speaker detection ZoomMtg.inMeetingServiceListener('onActiveSpeaker', (data) => { // [{userId: number, userName: string}] console.log('Active speaker:', data); }); // Network quality monitoring ZoomMtg.inMeetingServiceListener('onNetworkQualityChange', (data) => { // {level: 0-5, userId, type: 'uplink'} // 0-1 = bad, 2 = normal, 3-5 = good if (data.level <= 1) { console.warn('Poor network quality'); } }); // Join performance metrics ZoomMtg.inMeetingServiceListener('onJoinSpeed', (data) => { console.log('Join speed metrics:', data); // Useful for performance monitoring dashboards }); // Chat ZoomMtg.inMeetingServiceListener('onReceiveChatMsg', (data) => { console.log('Chat message:', data); }); // Recording ZoomMtg.inMeetingServiceListener('onRecordingChange', (data) => { console.log('Recording status:', data); }); // Screen sharing ZoomMtg.inMeetingServiceListener('onShareContentChange', (data) => { console.log('Share content changed:', data); }); // Transcription (requires "save closed captions" enabled) ZoomMtg.inMeetingServiceListener('onReceiveTranscriptionMsg', (data) => { console.log('Transcription:', data); }); // Breakout room status ZoomMtg.inMeetingServiceListener('onRoomStatusChange', (data) => { // status: 2=InProgress, 3=Closing, 4=Closed console.log('Breakout room status:', data); });
Common Methods (Client View)
// Get current user info ZoomMtg.getCurrentUser({ success: (res) => console.log(res.result.currentUser) }); // Get all attendees ZoomMtg.getAttendeeslist({}); // Audio/Video control ZoomMtg.mute({ userId, mute: true }); ZoomMtg.muteAll({ muteAll: true }); // Chat ZoomMtg.sendChat({ message: 'Hello!', userId: 0 }); // 0 = everyone // Leave/End ZoomMtg.leaveMeeting({}); ZoomMtg.endMeeting({}); // Host controls ZoomMtg.makeHost({ userId }); ZoomMtg.makeCoHost({ oderId }); ZoomMtg.expel({ userId }); // Remove participant ZoomMtg.putOnHold({ oderId, bHold: true }); // Breakout rooms ZoomMtg.createBreakoutRoom({ rooms: [...] }); ZoomMtg.openBreakoutRooms({}); ZoomMtg.closeBreakoutRooms({}); // Virtual background ZoomMtg.setVirtualBackground({ imageUrl: '...' });
Component View API Reference
client.init() - Key Options
await client.init({ // Required zoomAppRoot: HTMLElement, // Container element // Display language: string, // e.g., 'en-US' debug: boolean, // Enable debug logging (default: false) // Media patchJsMedia: boolean, // Auto-apply media fixes (default: false) leaveOnPageUnload: boolean, // Clean up on page unload (default: false) // Video enableHD: boolean, // Enable 720p enableFullHD: boolean, // Enable 1080p // Customization customize: { video: { isResizable: boolean, viewSizes: { default: { width, height } } }, meetingInfo: ['topic', 'host', 'mn', 'pwd', 'telPwd', 'invite', 'participant', 'dc', 'enctype'], toolbar: { buttons: [ { text: 'Custom Button', className: 'custom-btn', onClick: () => { console.log('Custom button clicked'); } } ] } }, // For ZFG webEndpoint: string, assetPath: string, // Custom path for AV libraries (self-hosting) });
client.join() - Key Options
await client.join({ // Required signature: string, sdkKey: string, meetingNumber: string | number, userName: string, // Authentication password: string, // Lowercase! (different from Client View) zak: string, // Host's ZAK token tk: string, // Registration token // Optional userEmail: string, });
Event Listeners (Component View)
// Connection state client.on('connection-change', (payload) => { // payload.state: 'Connecting', 'Connected', 'Reconnecting', 'Closed' console.log('Connection:', payload.state); }); // User events client.on('user-added', (payload) => { console.log('Users added:', payload); }); client.on('user-removed', (payload) => { console.log('Users removed:', payload); }); client.on('user-updated', (payload) => { console.log('Users updated:', payload); }); // Active speaker client.on('active-speaker', (payload) => { console.log('Active speaker:', payload); }); // Video state client.on('video-active-change', (payload) => { console.log('Video active:', payload); }); // Unsubscribe client.off('connection-change', handler);
Common Methods (Component View)
// Get current user const currentUser = client.getCurrentUser(); // Get all participants const participants = client.getParticipantsList(); // Audio control await client.mute(true); await client.muteAudio(userId, true); // Video control await client.muteVideo(userId, true); // Leave client.leaveMeeting(); // End (host only) client.endMeeting();
SharedArrayBuffer (CRITICAL for HD)
SharedArrayBuffer enables advanced features:
- 720p/1080p video
- Gallery view
- Virtual backgrounds
- Background noise suppression
Enable with HTTP Headers
Cross-Origin-Opener-Policy: same-origin Cross-Origin-Embedder-Policy: require-corp
Verify in Browser
if (typeof SharedArrayBuffer === 'function') { console.log('SharedArrayBuffer enabled!'); } else { console.warn('HD features will be limited'); } // Or check cross-origin isolation console.log('Cross-origin isolated:', window.crossOriginIsolated);
Platform-Specific Setup
See concepts/sharedarraybuffer.md for:
- Vercel, Netlify, AWS CloudFront configuration
- nginx/Apache configuration
- Service worker fallback for GitHub Pages
Development Setup (Two-Server Pattern)
The official samples use a two-server pattern for development because COOP/COEP headers can break navigation:
// Server 1: Main app (port 9999) - NO isolation headers // Serves index.html, navigation works normally // Server 2: Meeting page (port 9998) - WITH isolation headers // Serves meeting.html with SharedArrayBuffer support // Main server proxies to meeting server proxy: [{ path: '/meeting.html', target: 'http://YOUR_MEETING_SERVER_HOST:9998/' }]
Vite config with headers:
// vite.config.ts export default defineConfig({ server: { headers: { 'Cross-Origin-Embedder-Policy': 'require-corp', 'Cross-Origin-Opener-Policy': 'same-origin', } } });
Common Issues & Solutions
| Issue | Solution |
|---|---|
| Join fails with signature error | Verify signature generation, check sdkKey format |
| "passWord" typo | Client View uses (capital W), Component View uses |
| No HD video | Enable SharedArrayBuffer headers, check browser support |
| Callbacks not firing | Ensure called after init success |
| Virtual background not working | Requires SharedArrayBuffer + Chrome/Edge |
| Screen share fails on Safari | Safari 17+ with macOS 14+ required for client view |
Complete troubleshooting: troubleshooting/common-issues.md
Browser Support Matrix
| Feature | Chrome | Firefox | Safari | Edge | iOS | Android |
|---|---|---|---|---|---|---|
| 720p (receive) | Yes | Yes | Yes | Yes | Yes | Yes |
| 720p (send) | Yes* | Yes* | Yes* | Yes* | Yes* | Yes* |
| Virtual background | Yes | Yes | No | Yes | No | No |
| Screen share (send) | Yes | Yes | Safari 17+ | Yes | No | No |
| Gallery view | Yes | Yes | Yes** | Yes | Yes | Yes |
*Requires SharedArrayBuffer **Safari 17+ with macOS Sonoma
See concepts/browser-support.md for complete matrix.
Authorization Requirements (2026 Update)
IMPORTANT: Beginning March 2, 2026, apps joining meetings outside their account must be authorized.
Options
-
App Privilege Token (OBF) - Recommended for bots
ZoomMtg.join({ ... obfToken: 'your-app-privilege-token' }); -
ZAK Token - For host operations
ZoomMtg.join({ ... zak: 'host-zak-token' });
Zoom for Government (ZFG)
Option 1: ZFG-specific NPM Package
{ "dependencies": { "@zoom/meetingsdk": "3.11.2-zfg" } }
Option 2: Configure ZFG Endpoints
Client View:
ZoomMtg.setZoomJSLib('https://source.zoomgov.com/{VERSION}/lib', '/av'); ZoomMtg.init({ webEndpoint: 'www.zoomgov.com', ... });
Component View:
await client.init({ webEndpoint: 'www.zoomgov.com', assetPath: 'https://source.zoomgov.com/{VERSION}/lib/av', ... });
China CDN
// Set before preLoadWasm() ZoomMtg.setZoomJSLib('https://jssdk.zoomus.cn/{VERSION}/lib', '/av');
React Integration
Official Pattern (from zoom/meetingsdk-react-sample)
The official React sample uses imperative initialization rather than React hooks:
import { ZoomMtg } from '@zoom/meetingsdk'; // Preload at module level (outside component) ZoomMtg.preLoadWasm(); ZoomMtg.prepareWebSDK(); function App() { const authEndpoint = import.meta.env.VITE_AUTH_ENDPOINT; const meetingNumber = ''; const passWord = ''; const role = 0; const userName = 'React User'; const getSignature = async () => { const response = await fetch(authEndpoint, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ meetingNumber, role, }), }); const data = await response.json(); startMeeting(data.signature); }; const startMeeting = (signature: string) => { document.getElementById('zmmtg-root')!.style.display = 'block'; ZoomMtg.init({ leaveUrl: window.location.origin, patchJsMedia: true, leaveOnPageUnload: true, success: () => { ZoomMtg.join({ signature, meetingNumber, userName, passWord, success: (res) => console.log('Joined:', res), error: (err) => console.error('Join error:', err), }); }, error: (err) => console.error('Init error:', err), }); }; return ( <button onClick={getSignature}>Join Meeting</button> ); }
React Gotchas (from official samples)
| Issue | Problem | Solution |
|---|---|---|
| Client Recreation | in component body runs every render | Use to persist client |
| No useEffect | Official sample doesn't use React lifecycle hooks | SDK's handles cleanup |
| Direct DOM | Sample uses | Use in production |
| No Error State | Silent failures | Add for error handling |
| Module-Scope Side Effects | at top level | May cause issues with SSR |
Production-Ready React Pattern
import { useEffect, useRef, useState, useCallback } from 'react'; import ZoomMtgEmbedded from '@zoom/meetingsdk/embedded'; type ZoomClient = ReturnType<typeof ZoomMtgEmbedded.createClient>; function ZoomMeeting({ meetingNumber, password, userName }: Props) { const clientRef = useRef<ZoomClient | null>(null); const containerRef = useRef<HTMLDivElement>(null); const [isJoining, setIsJoining] = useState(false); const [error, setError] = useState<string | null>(null); // Create client once useEffect(() => { if (!clientRef.current) { clientRef.current = ZoomMtgEmbedded.createClient(); } }, []); const joinMeeting = useCallback(async () => { if (!clientRef.current || !containerRef.current) return; setIsJoining(true); setError(null); try { // Get signature from your backend const response = await fetch('/api/signature', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ meetingNumber, role: 0 }), }); const { signature, sdkKey } = await response.json(); await clientRef.current.init({ zoomAppRoot: containerRef.current, language: 'en-US', patchJsMedia: true, leaveOnPageUnload: true, }); await clientRef.current.join({ signature, sdkKey, meetingNumber, password, userName, }); } catch (err) { setError(err instanceof Error ? err.message : 'Failed to join'); } finally { setIsJoining(false); } }, [meetingNumber, password, userName]); return ( <div> <div ref={containerRef} style={{ width: '100%', height: '500px' }} /> <button onClick={joinMeeting} disabled={isJoining}> {isJoining ? 'Joining...' : 'Join Meeting'} </button> {error && <div className="error">{error}</div>} </div> ); }
Environment Variables (Vite)
# .env.local VITE_AUTH_ENDPOINT=http://YOUR_AUTH_SERVER_HOST:4000 VITE_SDK_KEY=your_sdk_key
const authEndpoint = import.meta.env.VITE_AUTH_ENDPOINT; const sdkKey = import.meta.env.VITE_SDK_KEY;
Detailed References
Core Documentation
- SKILL.md - Complete navigation guide
- client-view/SKILL.md - Full Client View reference
- component-view/SKILL.md - Full Component View reference
Concepts
- concepts/sharedarraybuffer.md - HD video requirements
- concepts/browser-support.md - Feature matrix by browser
Troubleshooting
- troubleshooting/error-codes.md - All SDK error codes
- troubleshooting/common-issues.md - Quick diagnostics
Examples
- client-view/SKILL.md - Complete Client View guide
- component-view/SKILL.md - Component View React integration
Helper Utilities
Extract Meeting Number from Invite Link
// Users can paste full Zoom invite links document.getElementById('meeting_number').addEventListener('input', (e) => { // Extract meeting number (9-11 digits) let meetingNumber = e.target.value.replace(/([^0-9])+/i, ''); if (meetingNumber.match(/([0-9]{9,11})/)) { meetingNumber = meetingNumber.match(/([0-9]{9,11})/)[1]; } // Auto-extract password from invite link const pwdMatch = e.target.value.match(/pwd=([\d,\w]+)/); if (pwdMatch) { document.getElementById('password').value = pwdMatch[1]; } });
Dynamic Language Switching
// Change language at runtime document.getElementById('language').addEventListener('change', (e) => { const lang = e.target.value; ZoomMtg.i18n.load(lang); ZoomMtg.i18n.reload(lang); ZoomMtg.reRender({ lang }); });
Check System Requirements
// Check browser compatibility before initializing const requirements = ZoomMtg.checkSystemRequirements(); console.log('Browser info:', JSON.stringify(requirements)); if (!requirements.browserInfo.isChrome && !requirements.browserInfo.isFirefox) { alert('For best experience, use Chrome or Firefox'); }
Sample Repositories
| Repository | Description |
|---|---|
| meetingsdk-web-sample | Official samples (Client View & Component View) |
| meetingsdk-react-sample | React integration with TypeScript + Vite |
| meetingsdk-web | SDK source with helper.html |
| meetingsdk-auth-endpoint-sample | Signature generation backend |
Official Resources
- Official docs: https://developers.zoom.us/docs/meeting-sdk/web/
- Client View API Reference: https://marketplacefront.zoom.us/sdk/meeting/web/index.html
- Component View API Reference: https://marketplacefront.zoom.us/sdk/meeting/web/components/index.html
- Developer forum: https://devforum.zoom.us/
Documentation Version: Based on Zoom Web Meeting SDK v3.11+
Need help? Start with SKILL.md for complete navigation.
Merged from meeting-sdk/web/SKILL.md
Zoom Meeting SDK (Web) - Documentation Index
Quick navigation guide for all Web SDK documentation.
Start Here
| Document | Description |
|---|---|
| SKILL.md | Main entry point - Quick starts for both Client View and Component View |
By View Type
Client View (Full-Page)
| Document | Description |
|---|---|
| client-view/SKILL.md | Complete Client View reference |
Component View (Embeddable)
| Document | Description |
|---|---|
| component-view/SKILL.md | Complete Component View reference |
Concepts
| Document | Description |
|---|---|
| concepts/sharedarraybuffer.md | HD video requirements, COOP/COEP headers |
| concepts/browser-support.md | Feature matrix by browser |
Examples
| Document | Description |
|---|---|
| examples/client-view-basic.md | Basic Client View integration |
| examples/component-view-react.md | React integration with Component View |
Troubleshooting
| Document | Description |
|---|---|
| troubleshooting/error-codes.md | All SDK error codes (3000-10000 range) |
| troubleshooting/common-issues.md | Quick diagnostics and fixes |
By Topic
Authentication
- SKILL.md#authentication-endpoint - Signature generation
- SKILL.md#authorization-requirements-2026-update - OBF tokens
HD Video & Performance
- concepts/sharedarraybuffer.md - Enable 720p/1080p
Events & Callbacks
- SKILL.md#event-listeners-client-view - Client View events
- SKILL.md#event-listeners-component-view - Component View events
Government (ZFG)
- SKILL.md#zoom-for-government-zfg - ZFG configuration
China CDN
- SKILL.md#china-cdn - China-specific CDN
Quick Reference
Client View vs Component View
| Aspect | Client View | Component View |
|---|---|---|
| Object | | |
| API Style | Callbacks | Promises |
| Password param | (capital W) | (lowercase) |
| Events | | / |
Key Gotchas
-
Password spelling differs between views!
- Client View:
(capital W)passWord - Component View:
(lowercase)password
- Client View:
-
SharedArrayBuffer required for HD features
- 720p/1080p video
- Gallery view (25 videos)
- Virtual backgrounds
-
March 2026 Authorization Change
- Apps joining external meetings need OBF or ZAK tokens
External Resources
- Official docs: https://developers.zoom.us/docs/meeting-sdk/web/
- Client View API: https://marketplacefront.zoom.us/sdk/meeting/web/index.html
- Component View API: https://marketplacefront.zoom.us/sdk/meeting/web/components/index.html
- GitHub samples: https://github.com/zoom/meetingsdk-web-sample
Operations
- RUNBOOK.md - 5-minute preflight and debugging checklist.