From zoom-plugin
Reference skill for Zoom Video SDK UI Toolkit. Use after routing to a web video workflow when you want prebuilt React UI instead of building a fully custom Video SDK interface.
npx claudepluginhub anthropics/claude-plugins-official --plugin zoom-pluginThis skill uses the workspace's default tool permissions.
Background reference for the prebuilt Zoom Video SDK UI Toolkit on web. Prefer `choose-zoom-approach` first when the user might still need Meeting SDK instead.
Reorganizes X and LinkedIn networks: review-first pruning of low-value follows, priority-based add/follow recommendations, and drafts warm outreach in user's voice.
Generates platform-native social content for X, LinkedIn, TikTok, YouTube, newsletters from source material like articles, demos, docs, or notes. Adapts voice and format per platform.
Interactively installs Everything Claude Code skills and rules to user-level (~/.claude) or project-level (.claude) directories, verifies paths, and optimizes files. Activate on 'configure ecc' or setup requests.
Background reference for the prebuilt Zoom Video SDK UI Toolkit on web. Prefer choose-zoom-approach first when the user might still need Meeting SDK instead.
Official Documentation: https://developers.zoom.us/docs/video-sdk/web/ui-toolkit/ API Reference: https://marketplacefront.zoom.us/sdk/uitoolkit/web/ NPM Package: https://www.npmjs.com/package/@zoom/videosdk-zoom-ui-toolkit Live Demo: https://sdk.zoom.com/videosdk-uitoolkit
New to UI Toolkit? Follow this path:
Having issues?
The Zoom Video SDK UI Toolkit is a pre-built video UI library that renders complete video conferencing experiences with minimal code. Unlike the raw Video SDK, the UI Toolkit provides:
When to use UI Toolkit:
When to use raw Video SDK instead:
npm install @zoom/videosdk-zoom-ui-toolkit jsrsasign
npm install -D @types/jsrsasign
Note: React support depends on the UI Toolkit version. Check the package peer dependencies for your installed version (React 18 is commonly required).
import uitoolkit from "@zoom/videosdk-zoom-ui-toolkit";
import "@zoom/videosdk-ui-toolkit/dist/videosdk-zoom-ui-toolkit.css";
const container = document.getElementById("sessionContainer");
const config = {
videoSDKJWT: "your_jwt_token",
sessionName: "my-session",
userName: "John Doe",
sessionPasscode: "",
features: ["video", "audio", "share", "chat", "users", "settings"],
};
uitoolkit.joinSession(container, config);
uitoolkit.onSessionJoined(() => {
console.log("Session joined");
});
uitoolkit.onSessionClosed(() => {
console.log("Session closed");
});
'use client';
import { useEffect, useRef } from 'react';
export default function VideoSession({ jwt, sessionName, userName }) {
const containerRef = useRef<HTMLDivElement>(null);
const uitoolkitRef = useRef<any>(null);
useEffect(() => {
let isMounted = true;
const init = async () => {
const uitoolkitModule = await import('@zoom/videosdk-zoom-ui-toolkit');
const uitoolkit = uitoolkitModule.default;
uitoolkitRef.current = uitoolkit;
// If TypeScript complains about CSS imports, configure your app to allow them
// (for example via a global `declare module \"*.css\";`), or import the CSS from
// a global entrypoint (Next.js layout/_app) instead of inlining here.
await import('@zoom/videosdk-ui-toolkit/dist/videosdk-zoom-ui-toolkit.css');
if (!isMounted || !containerRef.current) return;
const config: any = {
videoSDKJWT: jwt,
sessionName: sessionName,
userName: userName,
sessionPasscode: '',
features: ['video', 'audio', 'share', 'chat', 'users', 'settings'],
};
uitoolkit.joinSession(containerRef.current, config);
uitoolkit.onSessionJoined(() => console.log('Joined'));
uitoolkit.onSessionClosed(() => console.log('Closed'));
};
init();
return () => {
isMounted = false;
if (uitoolkitRef.current && containerRef.current) {
try {
uitoolkitRef.current.closeSession(containerRef.current);
} catch (e) {}
}
};
}, [jwt, sessionName, userName]);
return <div ref={containerRef} style={{ width: '100%', height: '100vh' }} />;
}
| Feature | Description |
|---|---|
video | Enable video layout and send/receive video |
audio | Show audio button, send/receive audio |
share | Screen sharing |
chat | In-session messaging |
users | Participant list |
settings | Device selection, virtual background |
preview | Pre-join camera/mic preview |
recording | Cloud recording (paid plan) |
leave | Leave/end session button |
Required: Generate JWT tokens on your server, never expose SDK secret client-side.
import { NextRequest, NextResponse } from 'next/server';
import { KJUR } from 'jsrsasign';
const ZOOM_VIDEO_SDK_KEY = process.env.ZOOM_VIDEO_SDK_KEY;
const ZOOM_VIDEO_SDK_SECRET = process.env.ZOOM_VIDEO_SDK_SECRET;
export async function POST(request: NextRequest) {
const { sessionName, role, userName } = await request.json();
if (!sessionName || role === undefined) {
return NextResponse.json({ error: 'Missing params' }, { status: 400 });
}
const iat = Math.floor(Date.now() / 1000);
const exp = iat + 60 * 60 * 2; // 2 hours
const oHeader = { alg: 'HS256', typ: 'JWT' };
const oPayload = {
app_key: ZOOM_VIDEO_SDK_KEY,
role_type: role, // 0 = participant, 1 = host
tpc: sessionName,
version: 1,
iat,
exp,
user_identity: userName || 'User',
};
const signature = KJUR.jws.JWS.sign(
'HS256',
JSON.stringify(oHeader),
JSON.stringify(oPayload),
ZOOM_VIDEO_SDK_SECRET
);
return NextResponse.json({ signature });
}
| Field | Required | Description |
|---|---|---|
app_key | Yes | Your Video SDK Key |
role_type | Yes | 0 = participant, 1 = host |
tpc | Yes | Session/topic name |
version | Yes | Always 1 |
iat | Yes | Issued at (Unix timestamp) |
exp | Yes | Expiration (Unix timestamp) |
user_identity | No | User identifier |
uitoolkit.joinSession(container, config);
uitoolkit.closeSession(container);
uitoolkit.onSessionJoined(callback);
uitoolkit.onSessionClosed(callback);
uitoolkit.offSessionJoined(callback);
uitoolkit.offSessionClosed(callback);
uitoolkit.showChatComponent(container);
uitoolkit.hideChatComponent(container);
uitoolkit.showUsersComponent(container);
uitoolkit.hideUsersComponent(container);
uitoolkit.showControlsComponent(container);
uitoolkit.hideControlsComponent(container);
uitoolkit.showSettingsComponent(container);
uitoolkit.hideSettingsComponent(container);
uitoolkit.hideAllComponents();
<link rel="stylesheet" href="https://source.zoom.us/uitoolkit/2.3.5-1/videosdk-zoom-ui-toolkit.css" />
<script src="https://source.zoom.us/uitoolkit/2.3.5-1/videosdk-zoom-ui-toolkit.min.umd.js"></script>
<div id="sessionContainer"></div>
<script>
const uitoolkit = window.UIToolkit;
uitoolkit.joinSession(document.getElementById('sessionContainer'), {
videoSDKJWT: 'your_jwt',
sessionName: 'my-session',
userName: 'User',
features: ['video', 'audio', 'chat']
});
</script>
When deploying Next.js under a subpath:
// next.config.ts
const nextConfig = {
basePath: "/your-app-path",
assetPrefix: "/your-app-path",
};
Fetch API routes with full path:
fetch('/your-app-path/api/token', { ... })
| Browser | Version |
|---|---|
| Chrome | 78+ |
| Firefox | 76+ |
| Safari | 14.1+ |
| Edge | 79+ |
| Issue | Solution |
|---|---|
peer react@"^18.0.0" error | Use the React version required by the installed UI Toolkit package (check peer deps; React 18 is common) |
| CSS import TypeScript error | Configure TS/CSS handling (prefer a global *.css module declaration); avoid @ts-ignore except in throwaway demos |
| Config type error | Type config as any |
| API returns HTML not JSON | Check basePath in fetch URL |
This section was migrated from SKILL.md.
Complete navigation for all UI Toolkit documentation.
New to the UI Toolkit? Follow this learning path:
Understanding how UI Toolkit works:
Complete API documentation:
Core Methods (see skill.md)
joinSession() - Start a video sessioncloseSession() - End session and remove UIdestroy() - Clean up UI Toolkit instanceleaveSession() - Leave without destroying UIComponent Methods (see skill.md)
showControlsComponent() - Display control barshowChatComponent() - Display chat panelshowUsersComponent() - Display participants listshowSettingsComponent() - Display settings panelhideAllComponents() - Hide all componentsEvent Listeners (see skill.md)
onSessionJoined() - Session joined successfullyonSessionClosed() - Session endedonSessionDestroyed() - UI Toolkit destroyedonViewTypeChange() - View mode changedon() - Subscribe to Video SDK eventsoff() - Unsubscribe from eventsInformation Methods (see skill.md)
getSessionInfo() - Get session detailsgetCurrentUserInfo() - Get current usergetAllUser() - Get all participantsgetClient() - Get underlying Video SDK clientversion() - Get version infoControl Methods (see skill.md)
changeViewType() - Switch view modemirrorVideo() - Mirror self videoisSupportCustomLayout() - Check device supportStatistics Methods (see skill.md)
subscribeAudioStatisticData() - Audio quality statssubscribeVideoStatisticData() - Video quality statssubscribeShareStatisticData() - Share quality statsFeature Configuration (see skill.md)
featuresOptions structureSession Configuration (see skill.md)
videoSDKJWT, sessionName, userNamesessionPasscode, sessionIdleTimeoutMinsSee: troubleshooting/common-issues.md
Official Repositories:
| Framework | Repository | Key Features |
|---|---|---|
| React | videosdk-zoom-ui-toolkit-react-sample | Hooks, TypeScript |
| Vue.js | videosdk-zoom-ui-toolkit-vuejs-sample | Composition API |
| Angular | videosdk-zoom-ui-toolkit-angular-sample | Services, Guards |
| JavaScript | videosdk-zoom-ui-toolkit-javascript-sample | Vanilla JS |
| Auth Endpoint | videosdk-auth-endpoint-sample | Node.js JWT |
import uitoolkit from "@zoom/videosdk-zoom-ui-toolkit";
import "@zoom/videosdk-ui-toolkit/dist/videosdk-zoom-ui-toolkit.css";
const config = {
videoSDKJWT: "YOUR_JWT",
sessionName: "test-session",
userName: "User",
featuresOptions: {
video: { enable: true },
audio: { enable: true }
}
};
uitoolkit.joinSession(document.getElementById("container"), config);
uitoolkit.onSessionJoined(() => console.log("Joined"));
uitoolkit.onSessionClosed(() => uitoolkit.destroy());
destroy() on cleanuponSessionClosed cleanupjoinSessionNavigation: ← Back to SKILL.md
.env keys and where to find each value.