> zoom-meeting-sdk-web-component-view
Zoom Meeting SDK Web - Component View. Embeddable Zoom meeting components with Promise-based API for flexible integration. Ideal for React/Vue/Angular apps and custom layouts. Uses ZoomMtgEmbedded with async/await patterns and embeddable UI containers.
curl "https://skillshub.wtf/zoom/skills/component-view?format=md"Zoom Meeting SDK Web - Component View
Embeddable Zoom meeting components for flexible integration into any web application. Component View provides Promise-based APIs and customizable UI.
This is the correct web skill for a custom UI around a real Zoom meeting. Do not route to Video SDK unless the user is building a non-meeting custom session product.
Overview
Component View uses ZoomMtgEmbedded.createClient() to create embeddable meeting components within a specific container element.
| Aspect | Details |
|---|---|
| API Object | ZoomMtgEmbedded.createClient() (instance) |
| API Style | Promise-based (async/await) |
| UI | Embeddable in any container |
| Password param | password (lowercase) |
| Events | on()/off() |
| Best For | Custom layouts, React/Vue/Angular apps |
Installation
NPM
npm install @zoom/meetingsdk --save
import ZoomMtgEmbedded from '@zoom/meetingsdk/embedded';
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-embedded-{VERSION}.min.js"></script>
Complete Initialization Flow
import ZoomMtgEmbedded from '@zoom/meetingsdk/embedded';
// Step 1: Create client instance (do once, not on every render!)
const client = ZoomMtgEmbedded.createClient();
async function joinMeeting() {
try {
// Step 2: Get container element
const meetingSDKElement = document.getElementById('meetingSDKElement');
// Step 3: Initialize client
await client.init({
zoomAppRoot: meetingSDKElement,
language: 'en-US',
debug: true,
patchJsMedia: true,
leaveOnPageUnload: true,
});
// Step 4: Join meeting
await client.join({
signature: signature,
sdkKey: sdkKey,
meetingNumber: meetingNumber,
userName: userName,
password: password, // lowercase!
userEmail: userEmail,
});
console.log('Joined successfully!');
} catch (error) {
console.error('Failed to join:', error);
}
}
client.init() - All Options
Required
| Parameter | Type | Description |
|---|---|---|
zoomAppRoot | HTMLElement | Container element for meeting UI |
Display
| Parameter | Type | Default | Description |
|---|---|---|---|
language | string | 'en-US' | UI language |
debug | boolean | false | Enable debug logging |
Media
| Parameter | Type | Default | Description |
|---|---|---|---|
patchJsMedia | boolean | false | Auto-apply media fixes |
leaveOnPageUnload | boolean | false | Cleanup on page unload |
enableHD | boolean | true | Enable 720p video |
enableFullHD | boolean | false | Enable 1080p video |
Customization
| Parameter | Type | Description |
|---|---|---|
customize | object | UI customization options |
webEndpoint | string | For ZFG: 'www.zoomgov.com' |
assetPath | string | Custom path for AV libraries |
Customize Object
await client.init({
zoomAppRoot: element,
customize: {
// Meeting info displayed
meetingInfo: [
'topic',
'host',
'mn',
'pwd',
'telPwd',
'invite',
'participant',
'dc',
'enctype'
],
// Video customization
video: {
isResizable: true,
viewSizes: {
default: {
width: 1000,
height: 600
},
ribbon: {
width: 300,
height: 700
}
},
popper: {
disableDraggable: false
}
},
// Custom toolbar buttons
toolbar: {
buttons: [
{
text: 'Custom Button',
className: 'custom-btn',
onClick: () => {
console.log('Custom button clicked');
}
}
]
},
// Active speaker indicator
activeSpaker: {
strokeColor: '#00FF00'
}
}
});
client.join() - All Options
Required
| Parameter | Type | Description |
|---|---|---|
signature | string | SDK JWT from backend |
sdkKey | string | SDK Key / Client ID |
meetingNumber | string | number | Meeting number |
userName | string | Display name |
Authentication
| Parameter | Type | When Required | Description |
|---|---|---|---|
password | string | If set | Meeting password (lowercase!) |
zak | string | Starting as host | Host's ZAK token |
tk | string | Registration | Registrant token |
userEmail | string | Webinars | User email |
Event Listeners
Syntax
// Subscribe
client.on('event-name', callback);
// Unsubscribe
client.off('event-name', callback);
Connection Events
client.on('connection-change', (payload) => {
// payload.state: 'Connecting', 'Connected', 'Reconnecting', 'Closed'
console.log('Connection state:', payload.state);
if (payload.state === 'Closed') {
console.log('Reason:', payload.reason);
}
});
User Events
client.on('user-added', (payload) => {
// Array of users who joined
console.log('Users added:', payload);
payload.forEach(user => {
console.log('User ID:', user.oderId);
console.log('Name:', user.displayName);
});
});
client.on('user-removed', (payload) => {
// Array of users who left
console.log('Users removed:', payload);
});
client.on('user-updated', (payload) => {
// Array of users whose properties changed
console.log('Users updated:', payload);
});
Audio Events
client.on('active-speaker', (payload) => {
// Current active speaker
console.log('Active speaker:', payload);
});
client.on('audio-statistic-data-change', (payload) => {
console.log('Audio stats:', payload);
});
Video Events
client.on('video-active-change', (payload) => {
// Video state changed
console.log('Video active:', payload);
});
client.on('video-statistic-data-change', (payload) => {
console.log('Video stats:', payload);
});
Share Events
client.on('active-share-change', (payload) => {
console.log('Share status:', payload);
});
client.on('share-statistic-data-change', (payload) => {
console.log('Share stats:', payload);
});
Chat Events
client.on('chat-on-message', (payload) => {
console.log('Chat message:', payload);
});
Recording Events
client.on('recording-change', (payload) => {
console.log('Recording status:', payload);
});
Media Device Events
client.on('media-sdk-change', (payload) => {
console.log('Media SDK:', payload);
});
client.on('device-change', () => {
console.log('Device changed');
});
Common Methods
User Information
// Get current user
const currentUser = client.getCurrentUser();
console.log('Current user:', currentUser);
// Get all participants
const participants = client.getParticipantsList();
console.log('Participants:', participants);
// Check if user is host
const isHost = client.isHost();
Audio Control
// Mute/unmute self
await client.mute(true); // mute
await client.mute(false); // unmute
// Mute/unmute specific user (host only)
await client.muteAudio(userId, true);
// Mute all (host only)
await client.muteAllAudio(true);
Video Control
// Start/stop video
await client.startVideo();
await client.stopVideo();
// Mute/unmute user's video (host only)
await client.muteVideo(userId, true);
Meeting Control
// Leave meeting
client.leaveMeeting();
// End meeting (host only)
client.endMeeting();
Screen Share
// Start screen share
await client.startShareScreen();
// Stop screen share
await client.stopShareScreen();
Recording
// Start recording (cloud)
await client.startCloudRecording();
// Stop recording
await client.stopCloudRecording();
Virtual Background
// Check support
const isSupported = await client.isSupportVirtualBackground();
// Set virtual background
await client.setVirtualBackground(imageUrl);
// Remove virtual background
await client.removeVirtualBackground();
Rename
// Rename user
await client.rename(userId, 'New Name');
React Integration
Basic 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 [isJoined, setIsJoined] = 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;
try {
// Get signature from backend
const { signature, sdkKey } = await fetchSignature(meetingNumber);
await clientRef.current.init({
zoomAppRoot: containerRef.current,
language: 'en-US',
patchJsMedia: true,
leaveOnPageUnload: true,
});
await clientRef.current.join({
signature,
sdkKey,
meetingNumber,
password,
userName,
});
setIsJoined(true);
} catch (err) {
setError(err instanceof Error ? err.message : 'Failed to join');
}
}, [meetingNumber, password, userName]);
return (
<div>
<div
ref={containerRef}
style={{ width: '100%', height: '500px' }}
/>
{!isJoined && (
<button onClick={joinMeeting}>Join Meeting</button>
)}
{error && <div className="error">{error}</div>}
</div>
);
}
Event Handling in React
useEffect(() => {
if (!clientRef.current) return;
const handleConnectionChange = (payload: any) => {
if (payload.state === 'Connected') {
setIsJoined(true);
} else if (payload.state === 'Closed') {
setIsJoined(false);
}
};
const handleUserAdded = (payload: any) => {
console.log('Users joined:', payload);
};
clientRef.current.on('connection-change', handleConnectionChange);
clientRef.current.on('user-added', handleUserAdded);
return () => {
clientRef.current?.off('connection-change', handleConnectionChange);
clientRef.current?.off('user-added', handleUserAdded);
};
}, []);
Positioning and Resizing
Initial Size
await client.init({
zoomAppRoot: element,
customize: {
video: {
viewSizes: {
default: { width: 1000, height: 600 }
}
}
}
});
Dynamic Resizing
The container element size determines the meeting UI size. To resize:
// Just resize the container
document.getElementById('meetingSDKElement').style.width = '1200px';
document.getElementById('meetingSDKElement').style.height = '800px';
Making it Resizable
customize: {
video: {
isResizable: true
}
}
Supported Features
Component View supports core meeting functionality. Some features from Client View may not be available.
| Feature | Supported |
|---|---|
| Audio/Video | ✅ |
| Screen Share | ✅ |
| Chat | ✅ |
| Virtual Background | ✅ |
| Breakout Rooms | ✅ |
| Cloud Recording | ✅ |
| Closed Captions | ✅ |
| Live Transcription | ✅ |
| Waiting Room | ✅ |
| Gallery View | ✅ |
| Reactions | ✅ |
| Raise Hand | ✅ |
Contact Zoom Developer Support to request additional features.
Error Handling
try {
await client.join({
// ... options
});
} catch (error) {
// error.reason contains error code
// error.message contains description
switch (error.reason) {
case 'WRONG_MEETING_PASSWORD':
console.error('Incorrect password');
break;
case 'MEETING_NOT_START':
console.error('Meeting has not started');
break;
case 'INVALID_PARAMETERS':
console.error('Invalid join parameters');
break;
default:
console.error('Join failed:', error.message);
}
}
Comparison with Client View
| Feature | Component View | Client View |
|---|---|---|
| API Style | Promises | Callbacks |
| Password param | password | passWord |
| Container | Custom element | Auto #zmmtg-root |
| UI | Embeddable | Full-page |
| Preloading | Not needed | preLoadWasm() |
| Language | Init option | i18n.load() |
| Events | on()/off() | inMeetingServiceListener() |
Resources
- Main Web SDK Skill
- Reference Index
- Error Codes
- Common Issues
- SharedArrayBuffer Setup
- Official API Reference
Operations
- RUNBOOK.md - 5-minute preflight and debugging checklist.
> related_skills --same-repo
> zoom-mcp/whiteboard
Zoom Whiteboard MCP server guidance. Use for Whiteboard MCP auth, endpoints, ID mapping, and tool workflows such as list_whiteboards and get_a_whiteboard. Prefer this child skill when the request is specifically about Whiteboard MCP rather than general Zoom MCP.
> zoom-mcp
Official Zoom MCP Server guidance for AI-agent access to semantic meeting search, meeting assets, recording resources, and Zoom Docs creation over MCP. Use when the request is about Zoom tools/list or tools/call against Zoom's hosted MCP endpoints, AI Companion retrieval, recording-content access, or Zoom Docs creation via MCP. Route Whiteboard-specific MCP requests to zoom-mcp/whiteboard.
> zoom-apps-sdk
Zoom Apps SDK for building web apps that run inside the Zoom client. JavaScript SDK (@zoom/appssdk) for in-meeting experiences, Layers API for immersive visuals, Collaborate Mode for shared state, and In-Client OAuth for seamless authorization. Use when building apps that appear within Zoom meetings, webinars, the main client, or Zoom Phone.
> zoom-websockets
Zoom WebSockets for real-time event notifications via persistent connection. Alternative to webhooks with lower latency, bidirectional communication, and enhanced security. Use when you need real-time event updates, are in security-sensitive industries, or want faster event delivery than webhooks.