zoom-apps-sdk

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Zoom Apps SDK

Zoom Apps SDK

Background reference for web apps that run inside the Zoom client. Prefer
choose-zoom-approach
first, then route here for Layers API, Collaborate Mode, in-client OAuth, and runtime constraints.
适用于Zoom客户端内运行的Web应用的背景参考文档。建议先使用
choose-zoom-approach
,之后可在此查阅Layers API、协作模式、客户端内OAuth及运行时约束相关内容。

Zoom Apps SDK

Zoom Apps SDK

Build web apps that run inside the Zoom client - meetings, webinars, main client, and Zoom Phone.
构建可运行于Zoom客户端(会议、网络研讨会、主客户端及Zoom Phone)中的Web应用。

Quick Links

快速链接

New to Zoom Apps? Follow this path:
  1. Architecture - Frontend/backend pattern, embedded browser, deep linking
  2. Quick Start - Complete working Express + SDK app
  3. Running Contexts - Where your app runs (inMeeting, inMainClient, etc.)
  4. Zoom Apps vs Meeting SDK - Stop mixing app types
  5. In-Client OAuth - Seamless authorization with PKCE
  6. API Reference - 100+ SDK methods
  7. Integrated Index - see the section below in this file
  8. 5-Minute Runbook - Preflight checks before deep debugging
Reference:
  • API Reference - All SDK methods by category
  • Events Reference - All SDK event listeners
  • Layers API - Immersive and camera mode rendering
  • OAuth Reference - OAuth flows for Zoom Apps
  • Zoom Mail - Mail plugin integration
Having issues?
  • App won't load in Zoom → Check Domain Allowlist below
  • SDK errors → Common Issues
  • Local dev setup → Debugging Guide
  • Version upgrade → Migration Guide
  • Forum-derived FAQs → Forum Top Questions
Building immersive experiences?
  • Layers Immersive Mode - Custom video layouts
  • Camera Mode - Virtual camera overlays
Need help with OAuth? See the zoom-oauth skill for authentication flows.
首次接触Zoom Apps?请遵循以下路径:
  1. 架构 - 前端/后端模式、嵌入式浏览器、深度链接
  2. 快速开始 - 完整可运行的Express + SDK应用
  3. 运行上下文 - 应用运行位置(inMeeting、inMainClient等)
  4. Zoom Apps vs 会议SDK - 区分不同应用类型
  5. 客户端内OAuth - 基于PKCE的无缝授权
  6. API参考 - 100+ SDK方法
  7. 集成索引 - 见本文档下方对应章节
  8. 5分钟运行手册 - 深度调试前的预检检查
参考内容:
  • API参考 - 按类别划分的所有SDK方法
  • 事件参考 - 所有SDK事件监听器
  • Layers API - 沉浸式及摄像头模式渲染
  • OAuth参考 - Zoom Apps的OAuth流程
  • Zoom Mail - 邮件插件集成
遇到问题?
  • 应用无法在Zoom中加载 → 检查下方的域名白名单
  • SDK错误 → 常见问题
  • 本地开发设置 → 调试指南
  • 版本升级 → 迁移指南
  • 论坛常见问题 → 论坛热门问题
构建沉浸式体验?
  • Layers沉浸式模式 - 自定义视频布局
  • 摄像头模式 - 虚拟摄像头叠加层
需要OAuth相关帮助? 请查看**zoom-oauth**技能文档了解认证流程。

SDK Overview

SDK概述

The Zoom Apps SDK (
@zoom/appssdk
) provides JavaScript APIs for web apps running in Zoom's embedded browser:
  • Context APIs - Get meeting, user, and participant info
  • Meeting Actions - Share app, invite participants, open URLs
  • Authorization - In-Client OAuth with PKCE (no browser redirect)
  • Layers API - Immersive video layouts and camera mode overlays
  • Collaborate Mode - Shared app state across participants
  • App Communication - Message passing between app instances (main client <-> meeting)
  • Media Controls - Virtual backgrounds, camera listing, recording control
  • UI Controls - Expand app, notifications, popout
  • Events - React to meeting state, participants, sharing, and more
Zoom Apps SDK (
@zoom/appssdk
) 为运行在Zoom嵌入式浏览器中的Web应用提供JavaScript API:
  • 上下文API - 获取会议、用户及参会者信息
  • 会议操作 - 分享应用、邀请参会者、打开URL
  • 授权 - 基于PKCE的客户端内OAuth(无需浏览器重定向)
  • Layers API - 沉浸式视频布局及摄像头模式叠加层
  • 协作模式 - 跨参会者的共享应用状态
  • 应用通信 - 应用实例间的消息传递(主客户端 <-> 会议)
  • 媒体控制 - 虚拟背景、摄像头列表、录制控制
  • UI控制 - 展开应用、通知、弹出窗口
  • 事件 - 响应会议状态、参会者、共享等变化

Prerequisites

前置条件

  • Zoom app configured as "Zoom App" type in Marketplace
  • OAuth credentials (Client ID + Secret) with Zoom Apps scopes
  • Web application (Node.js + Express recommended)
  • Your domain whitelisted in Marketplace domain allowlist
  • ngrok or HTTPS tunnel for local development
  • Node.js 18+ (for the backend server)
  • Marketplace中配置为**"Zoom App"**类型的应用
  • 带有Zoom Apps权限范围的OAuth凭据(Client ID + Secret)
  • Web应用(推荐使用Node.js + Express)
  • 域名已在Marketplace域名白名单中
  • 用于本地开发的ngrok或HTTPS隧道
  • Node.js 18+(用于后端服务器)

Quick Start

快速开始

Option A: NPM (Recommended for frameworks)

选项A:NPM(框架推荐使用)

bash
npm install @zoom/appssdk
javascript
import zoomSdk from '@zoom/appssdk';

async function init() {
  try {
    const configResponse = await zoomSdk.config({
      capabilities: [
        'shareApp',
        'getMeetingContext',
        'getUserContext',
        'openUrl'
      ],
      version: '0.16'
    });

    console.log('Running context:', configResponse.runningContext);
    // 'inMeeting' | 'inMainClient' | 'inWebinar' | 'inImmersive' | ...

    const context = await zoomSdk.getMeetingContext();
    console.log('Meeting ID:', context.meetingID);
  } catch (error) {
    console.error('Not running inside Zoom:', error.message);
    showDemoMode();
  }
}
bash
npm install @zoom/appssdk
javascript
import zoomSdk from '@zoom/appssdk';

async function init() {
  try {
    const configResponse = await zoomSdk.config({
      capabilities: [
        'shareApp',
        'getMeetingContext',
        'getUserContext',
        'openUrl'
      ],
      version: '0.16'
    });

    console.log('Running context:', configResponse.runningContext);
    // 'inMeeting' | 'inMainClient' | 'inWebinar' | 'inImmersive' | ...

    const context = await zoomSdk.getMeetingContext();
    console.log('Meeting ID:', context.meetingID);
  } catch (error) {
    console.error('Not running inside Zoom:', error.message);
    showDemoMode();
  }
}

Option B: CDN (Vanilla JS)

选项B:CDN(原生JS使用)

html
<script src="https://appssdk.zoom.us/sdk.js"></script>

<script>
// CRITICAL: Do NOT declare "let zoomSdk" - the SDK defines window.zoomSdk globally
// Using "let zoomSdk = ..." causes: SyntaxError: redeclaration of non-configurable global property
let sdk = window.zoomSdk;  // Use a different variable name

async function init() {
  try {
    const configResponse = await sdk.config({
      capabilities: ['shareApp', 'getMeetingContext', 'getUserContext'],
      version: '0.16'
    });

    console.log('Running context:', configResponse.runningContext);
  } catch (error) {
    console.error('Not running inside Zoom:', error.message);
    showDemoMode();
  }
}

function showDemoMode() {
  document.body.innerHTML = '<h1>Preview Mode</h1><p>Open this app inside Zoom to use.</p>';
}

document.addEventListener('DOMContentLoaded', () => {
  init();
  setTimeout(() => { if (!sdk) showDemoMode(); }, 3000);
});
</script>
html
<script src="https://appssdk.zoom.us/sdk.js"></script>

<script>
// 重要:请勿声明"let zoomSdk" - SDK已全局定义window.zoomSdk
// 使用"let zoomSdk = ..."会导致:SyntaxError: redeclaration of non-configurable global property
let sdk = window.zoomSdk;  // 使用不同的变量名

async function init() {
  try {
    const configResponse = await sdk.config({
      capabilities: ['shareApp', 'getMeetingContext', 'getUserContext'],
      version: '0.16'
    });

    console.log('Running context:', configResponse.runningContext);
  } catch (error) {
    console.error('Not running inside Zoom:', error.message);
    showDemoMode();
  }
}

function showDemoMode() {
  document.body.innerHTML = '<h1>预览模式</h1><p>请在Zoom客户端内打开此应用以使用全部功能。</p>';
}

document.addEventListener('DOMContentLoaded', () => {
  init();
  setTimeout(() => { if (!sdk) showDemoMode(); }, 3000);
});
</script>

Critical: Global Variable Conflict

重要提示:全局变量冲突

The CDN script defines
window.zoomSdk
globally. Do NOT redeclare it:
javascript
// WRONG - causes SyntaxError in Zoom's embedded browser
let zoomSdk = null;
zoomSdk = window.zoomSdk;

// CORRECT - use different variable name
let sdk = window.zoomSdk;

// ALSO CORRECT - NPM import (no conflict)
import zoomSdk from '@zoom/appssdk';
This only applies to the CDN approach. The NPM import creates a module-scoped variable, no conflict.
CDN脚本会全局定义
window.zoomSdk
请勿重新声明它:
javascript
// 错误示例 - 在Zoom嵌入式浏览器中会导致SyntaxError
let zoomSdk = null;
zoomSdk = window.zoomSdk;

// 正确示例 - 使用不同的变量名
let sdk = window.zoomSdk;

// 同样正确 - NPM导入(无冲突)
import zoomSdk from '@zoom/appssdk';
此问题仅存在于CDN引入方式。NPM导入会创建模块作用域变量,不会产生冲突。

Browser Preview / Demo Mode

浏览器预览/演示模式

The SDK only functions inside the Zoom client. When accessed in a regular browser:
  • window.zoomSdk
    exists but
    sdk.config()
    throws an error
  • Always implement try/catch with fallback UI
  • Add timeout (3 seconds) in case SDK hangs
SDK仅在Zoom客户端内正常工作。在常规浏览器中访问时:
  • window.zoomSdk
    存在,但
    sdk.config()
    会抛出错误
  • 务必实现try/catch并提供回退UI
  • 添加超时(3秒)以防SDK加载卡顿

URL Whitelisting (Required)

URL白名单(必填)

Your app will NOT load in Zoom unless the domain is whitelisted.
  1. Go to Zoom Marketplace
  2. Open your app -> Feature tab
  3. Under Zoom App, find Add Allow List
  4. Add your domain (e.g.,
    yourdomain.com
    for production,
    xxxxx.ngrok.io
    for dev)
Without this, the Zoom client shows a blank panel with no error message.
除非域名已在白名单中,否则您的应用无法在Zoom中加载。
  1. 访问Zoom Marketplace
  2. 打开您的应用 -> 功能标签页
  3. Zoom App下找到添加允许列表
  4. 添加您的域名(例如生产环境的
    yourdomain.com
    ,开发环境的
    xxxxx.ngrok.io
如果未配置白名单,Zoom客户端会显示空白面板且无任何错误提示。

OAuth Scopes (Required)

OAuth权限范围(必填)

Capabilities require matching OAuth scopes enabled in Marketplace:
CapabilityRequired Scope
getMeetingContext
zoomapp:inmeeting
getUserContext
zoomapp:inmeeting
shareApp
zoomapp:inmeeting
openUrl
zoomapp:inmeeting
sendAppInvitation
zoomapp:inmeeting
runRenderingContext
zoomapp:inmeeting
authorize
zoomapp:inmeeting
getMeetingParticipants
zoomapp:inmeeting
To add scopes: Marketplace -> Your App -> Scopes tab -> Add required scopes.
Missing scopes = capability fails silently or throws error. Users must re-authorize if you add new scopes.
使用对应功能需要在Marketplace中启用匹配的OAuth权限范围:
功能所需权限范围
getMeetingContext
zoomapp:inmeeting
getUserContext
zoomapp:inmeeting
shareApp
zoomapp:inmeeting
openUrl
zoomapp:inmeeting
sendAppInvitation
zoomapp:inmeeting
runRenderingContext
zoomapp:inmeeting
authorize
zoomapp:inmeeting
getMeetingParticipants
zoomapp:inmeeting
添加权限范围: Marketplace -> 您的应用 -> 权限范围标签页 -> 添加所需的权限范围。
缺少权限范围会导致功能静默失败或抛出错误。如果您添加了新的权限范围,用户必须重新授权应用。

Running Contexts

运行上下文

Your app runs in different surfaces within Zoom. The
configResponse.runningContext
tells you where:
ContextSurfaceDescription
inMeeting
Meeting sidebarMost common. Full meeting APIs available
inMainClient
Main client panelHome tab. No meeting context APIs
inWebinar
Webinar sidebarHost/panelist. Meeting + webinar APIs
inImmersive
Layers APIFull-screen custom rendering
inCamera
Camera modeVirtual camera overlay
inCollaborate
Collaborate modeShared state context
inPhone
Zoom PhonePhone call app
inChat
Team ChatChat sidebar
See Running Contexts for context-specific behavior and APIs.
您的应用可在Zoom内的不同场景中运行。
configResponse.runningContext
会告知您当前的运行位置:
上下文场景描述
inMeeting
会议侧边栏最常见场景,支持所有会议API
inMainClient
主客户端面板首页标签页,无会议上下文API
inWebinar
网络研讨会侧边栏主持人/嘉宾可用,支持会议+网络研讨会API
inImmersive
Layers API全屏自定义渲染
inCamera
摄像头模式虚拟摄像头叠加层
inCollaborate
协作模式共享状态上下文
inPhone
Zoom Phone电话通话应用
inChat
团队聊天聊天侧边栏
详情请查看**运行上下文**了解各上下文的特定行为及可用API。

SDK Initialization Pattern

SDK初始化模式

Every Zoom App starts with
config()
:
javascript
import zoomSdk from '@zoom/appssdk';

const configResponse = await zoomSdk.config({
  capabilities: [
    // List ALL APIs you will use
    'getMeetingContext',
    'getUserContext',
    'shareApp',
    'openUrl',
    'authorize',
    'onAuthorized'
  ],
  version: '0.16'
});

// configResponse contains:
// {
//   runningContext: 'inMeeting',
//   clientVersion: '5.x.x',
//   unsupportedApis: []  // APIs not supported in this client version
// }
Rules:
  1. config()
    MUST be called before any other SDK method
  2. Only capabilities listed in
    config()
    are available
  3. Capabilities must match OAuth scopes in Marketplace
  4. Check
    unsupportedApis
    for graceful degradation
每个Zoom App都需从
config()
开始:
javascript
import zoomSdk from '@zoom/appssdk';

const configResponse = await zoomSdk.config({
  capabilities: [
    // 列出所有您将使用的API
    'getMeetingContext',
    'getUserContext',
    'shareApp',
    'openUrl',
    'authorize',
    'onAuthorized'
  ],
  version: '0.16'
});

// configResponse包含:
// {
//   runningContext: 'inMeeting',
//   clientVersion: '5.x.x',
//   unsupportedApis: []  // 此客户端版本不支持的API
// }
规则:
  1. config()
    必须在调用任何其他SDK方法之前执行
  2. config()
    中列出的功能可用
  3. 功能必须与Marketplace中的OAuth权限范围匹配
  4. 检查
    unsupportedApis
    以实现优雅降级

In-Client OAuth (Summary)

客户端内OAuth(概述)

Best UX for authorization - no browser redirect:
javascript
// 1. Get code challenge from your backend
const { codeChallenge, state } = await fetch('/api/auth/challenge').then(r => r.json());

// 2. Trigger in-client authorization
await zoomSdk.authorize({ codeChallenge, state });

// 3. Listen for authorization result
zoomSdk.addEventListener('onAuthorized', async (event) => {
  const { code, state } = event;
  // 4. Send code to backend for token exchange
  await fetch('/api/auth/token', {
    method: 'POST',
    body: JSON.stringify({ code, state })
  });
});
See In-Client OAuth Guide for complete implementation.
最佳授权体验 - 无需浏览器重定向:
javascript
// 1. 从后端获取code challenge
const { codeChallenge, state } = await fetch('/api/auth/challenge').then(r => r.json());

// 2. 触发客户端内授权
await zoomSdk.authorize({ codeChallenge, state });

// 3. 监听授权结果
zoomSdk.addEventListener('onAuthorized', async (event) => {
  const { code, state } = event;
  // 4. 将code发送至后端以交换令牌
  await fetch('/api/auth/token', {
    method: 'POST',
    body: JSON.stringify({ code, state })
  });
});
完整实现请查看**客户端内OAuth指南**。

Layers API (Summary)

Layers API(概述)

Build immersive video layouts and camera overlays:
javascript
// Start immersive mode - replaces gallery view
await zoomSdk.runRenderingContext({ view: 'immersive' });

// Position participant video feeds
await zoomSdk.drawParticipant({
  participantUUID: 'user-uuid',
  x: 0, y: 0, width: 640, height: 480, zIndex: 1
});

// Add overlay images
await zoomSdk.drawImage({
  imageData: canvas.toDataURL(),
  x: 0, y: 0, width: 1280, height: 720, zIndex: 0
});

// Exit immersive mode
await zoomSdk.closeRenderingContext();
See Layers Immersive and Camera Mode.
构建沉浸式视频布局及摄像头叠加层:
javascript
// 启动沉浸式模式 - 替换画廊视图
await zoomSdk.runRenderingContext({ view: 'immersive' });

// 定位参会者视频流
await zoomSdk.drawParticipant({
  participantUUID: 'user-uuid',
  x: 0, y: 0, width: 640, height: 480, zIndex: 1
});

// 添加叠加图片
await zoomSdk.drawImage({
  imageData: canvas.toDataURL(),
  x: 0, y: 0, width: 1280, height: 720, zIndex: 0
});

// 退出沉浸式模式
await zoomSdk.closeRenderingContext();
详情请查看**Layers沉浸式模式摄像头模式**。

Environment Variables

环境变量

VariableDescriptionWhere to Find
ZOOM_APP_CLIENT_ID
App client IDMarketplace -> App -> App Credentials
ZOOM_APP_CLIENT_SECRET
App client secretMarketplace -> App -> App Credentials
ZOOM_APP_REDIRECT_URI
OAuth redirect URLYour server URL +
/auth
SESSION_SECRET
Cookie signing secretGenerate random string
ZOOM_HOST
Zoom host URL
https://zoom.us
(or
https://zoomgov.com
)
变量描述获取位置
ZOOM_APP_CLIENT_ID
应用客户端IDMarketplace -> 应用 -> 应用凭据
ZOOM_APP_CLIENT_SECRET
应用客户端密钥Marketplace -> 应用 -> 应用凭据
ZOOM_APP_REDIRECT_URI
OAuth重定向URL您的服务器URL +
/auth
SESSION_SECRET
Cookie签名密钥生成随机字符串
ZOOM_HOST
Zoom主机URL
https://zoom.us
(或
https://zoomgov.com

Common APIs

常用API

APIDescription
config()
Initialize SDK, request capabilities
getMeetingContext()
Get meeting ID, topic, status
getUserContext()
Get user name, role, participant ID
getRunningContext()
Get current running context
getMeetingParticipants()
List participants
shareApp()
Share app screen with participants
openUrl({ url })
Open URL in external browser
sendAppInvitation()
Invite users to open your app
authorize()
Trigger In-Client OAuth
connect()
Connect to other app instances
postMessage()
Send message to connected instances
runRenderingContext()
Start Layers API (immersive/camera)
expandApp({ action })
Expand/collapse app panel
showNotification()
Show notification in Zoom
API描述
config()
初始化SDK,请求所需功能
getMeetingContext()
获取会议ID、主题、状态
getUserContext()
获取用户名、角色、参会者ID
getRunningContext()
获取当前运行上下文
getMeetingParticipants()
列出参会者
shareApp()
向参会者共享应用屏幕
openUrl({ url })
在外部浏览器中打开URL
sendAppInvitation()
邀请用户打开您的应用
authorize()
触发客户端内OAuth
connect()
连接到其他应用实例
postMessage()
向已连接的实例发送消息
runRenderingContext()
启动Layers API(沉浸式/摄像头模式)
expandApp({ action })
展开/折叠应用面板
showNotification()
在Zoom中显示通知

Complete Documentation Library

完整文档库

Core Concepts

核心概念

  • Architecture - Frontend/backend pattern, embedded browser, deep linking, X-Zoom-App-Context
  • Running Contexts - All contexts, context-specific APIs, multi-instance communication
  • Security - OWASP headers, CSP, cookie security, PKCE, token storage
  • 架构 - 前端/后端模式、嵌入式浏览器、深度链接、X-Zoom-App-Context
  • 运行上下文 - 所有上下文、各上下文专属API、多实例通信
  • 安全 - OWASP头、CSP、数据访问层

Complete Examples

完整示例

  • Quick Start - Hello World Express + SDK app
  • In-Client OAuth - PKCE authorization flow
  • Layers Immersive - Custom video layouts
  • Camera Mode - Virtual camera overlays
  • Collaborate Mode - Shared state across participants
  • Guest Mode - Unauthenticated/authenticated/authorized states
  • Breakout Rooms - Room detection and cross-room state
  • App Communication - connect + postMessage between instances
  • 快速开始 - Hello World极简Express + SDK应用
  • 客户端内OAuth - 基于PKCE的授权流程
  • Layers沉浸式模式 - Layers API - 沉浸式模式(自定义布局)
  • 摄像头模式 - Layers API - 摄像头模式(虚拟摄像头)
  • 协作模式 - 协作模式(共享状态)
  • 访客模式 - 访客模式(未认证->已授权状态)
  • breakout rooms - 分组讨论室集成
  • 应用通信 - connect + postMessage实例间通信

Troubleshooting

故障排除

  • Common Issues - Quick diagnostics and error codes
  • Debugging - Local dev, ngrok, browser preview
  • Migration - SDK version upgrade notes
  • 常见问题 - 快速诊断及错误代码
  • 调试 - 本地开发设置、ngrok、浏览器预览
  • 迁移 - SDK版本迁移说明

References

参考文档

  • API Reference - All 100+ SDK methods
  • Events Reference - All SDK event listeners
  • Layers API Reference - Drawing and rendering methods
  • OAuth Reference - OAuth flows for Zoom Apps
  • Zoom Mail - Mail plugin integration
  • API参考 - 全部100+ SDK方法
  • 事件参考 - 所有SDK事件
  • Layers API参考 - 绘图及渲染方法
  • OAuth参考 - Zoom Apps的OAuth流程
  • Zoom Mail参考 - Zoom Mail集成

Sample Repositories

示例仓库

Official (by Zoom)

官方(Zoom提供)

RepositoryTypeLast UpdatedStatusSDK Version
zoomapps-sample-jsHello World (Vanilla JS)Dec 2025Active^0.16.26
zoomapps-advancedsample-reactAdvanced (React + Redis)Oct 2025Active0.16.0
zoomapps-customlayout-jsLayers APINov 2023Stale^0.16.8
zoomapps-texteditor-vuejsCollaborate (Vue + Y.js)Oct 2023Stale^0.16.7
zoomapps-serverless-vuejsServerless (Firebase)Aug 2024Stale^0.16.21
zoomapps-cameramode-vuejsCamera Mode---
zoomapps-workshop-sampleWorkshop---
Recommended for new projects: Use
@zoom/appssdk
version
^0.16.26
.
仓库类型最后更新时间状态SDK版本
zoomapps-sample-jsHello World(原生JS)2025年12月活跃^0.16.26
zoomapps-advancedsample-react进阶示例(React + Redis)2025年10月活跃0.16.0
zoomapps-customlayout-jsLayers API2023年11月已停止维护^0.16.8
zoomapps-texteditor-vuejs协作示例(Vue + Y.js)2023年10月已停止维护^0.16.7
zoomapps-serverless-vuejs无服务器示例(Firebase)2024年8月已停止维护^0.16.21
zoomapps-cameramode-vuejs摄像头模式---
zoomapps-workshop-sample研讨会示例---
新项目推荐: 使用
@zoom/appssdk
版本
^0.16.26

Community

社区贡献

TypeRepositoryDescription
Libraryharvard-edtech/zacclZoom App Complete Connection Library
Full list: See general/references/community-repos.md
类型仓库描述
harvard-edtech/zacclZoom App完整连接库
完整列表:请查看general/references/community-repos.md

Learning Path

学习路径

  1. Start:
    zoomapps-sample-js
    - Simplest, most up-to-date
  2. Advanced:
    zoomapps-advancedsample-react
    - Comprehensive (In-Client OAuth, Guest Mode, Collaborate)
  3. Specialized: Pick based on feature (Layers, Serverless, Camera Mode)
  1. 入门
    zoomapps-sample-js
    - 最简、最新的示例
  2. 进阶
    zoomapps-advancedsample-react
    - 全面覆盖(客户端内OAuth、访客模式、协作模式)
  3. 专项:根据所需功能选择对应示例(Layers、无服务器、摄像头模式)

Critical Gotchas (From Real Development)

关键注意事项(来自实际开发经验)

1. Global Variable Conflict

1. 全局变量冲突

The CDN script defines
window.zoomSdk
. Declaring
let zoomSdk
in your code causes
SyntaxError: redeclaration of non-configurable global property
. Use
let sdk = window.zoomSdk
or the NPM import.
CDN脚本会全局定义
window.zoomSdk
。在代码中声明
let zoomSdk
会导致
SyntaxError: redeclaration of non-configurable global property
。请使用
let sdk = window.zoomSdk
或NPM导入方式。

2. Domain Allowlist

2. 域名白名单

Your app URL must be in the Marketplace domain allowlist. Without it, Zoom shows a blank panel with no error. Also add
appssdk.zoom.us
and any CDN domains you use.
您的应用URL必须在Marketplace域名白名单中。如果未配置,Zoom会显示空白面板且无任何错误提示。同时需添加
appssdk.zoom.us
及您使用的所有CDN域名。

3. Capabilities Must Be Listed

3. 必须列出所有功能

Only APIs listed in
config({ capabilities: [...] })
are available. Calling an unlisted API throws an error. This is also true for event listeners.
config({ capabilities: [...] })
中列出的API可用。调用未列出的API会抛出错误。事件监听器同样需要列出。

4. SDK Only Works Inside Zoom

4. SDK仅在Zoom客户端内工作

zoomSdk.config()
throws outside the Zoom client. Always wrap in try/catch with browser fallback:
javascript
try { await zoomSdk.config({...}); } catch { showBrowserPreview(); }
zoomSdk.config()
在Zoom客户端外会抛出错误。请始终用try/catch包裹并提供浏览器回退方案:
javascript
try { await zoomSdk.config({...}); } catch { showBrowserPreview(); }

5. ngrok URL Changes

5. ngrok URL会变化

Free ngrok URLs change on restart. You must update 4 places in Marketplace: Home URL, Redirect URL, OAuth Allow List, Domain Allow List. Consider ngrok paid plan for stable subdomain.
免费版ngrok URL在重启后会改变。您必须在Marketplace的4个位置更新:主页URL、重定向URL、OAuth允许列表、域名允许列表。考虑使用ngrok付费方案以获取稳定子域名。

6. In-Client OAuth vs Web OAuth

6. 客户端内OAuth优于Web OAuth

Use
zoomSdk.authorize()
(In-Client) for best UX - no browser redirect. Only fall back to web redirect for initial install from Marketplace.
使用
zoomSdk.authorize()
(客户端内)可获得最佳用户体验 - 无需浏览器重定向。仅在从Marketplace首次安装时才需要回退到Web重定向。

7. Camera Mode CEF Race Condition

7. 摄像头模式存在CEF竞争条件

Camera mode uses CEF which takes time to initialize.
drawImage
/
drawWebView
may fail if called too early. Implement retry with exponential backoff.
摄像头模式使用CEF,初始化需要时间。如果过早调用
drawImage
/
drawWebView
可能会失败。请实现指数退避重试机制。

8. Cookie Configuration

8. Cookie配置

Zoom's embedded browser requires cookies with
SameSite=None
and
Secure=true
. Without this, sessions break silently.
Zoom嵌入式浏览器要求Cookie设置
SameSite=None
Secure=true
。否则会话会静默失效。

9. State Validation

9. 状态验证

Always validate the OAuth
state
parameter to prevent CSRF attacks. Generate cryptographically random state, store it, and verify on callback.
始终验证OAuth的
state
参数以防止CSRF攻击。生成加密随机状态,存储并在回调时验证。

Resources

资源


Need help? Start with Integrated Index section below for complete navigation.


需要帮助? 请查看下方的集成索引章节获取完整导航。

Integrated Index

集成索引

This section was migrated from
SKILL.md
.
此章节迁移自
SKILL.md

Quick Start Path

快速开始路径

If you're new to Zoom Apps, follow this order:
  1. Run preflight checks first -> RUNBOOK.md
  2. Read the architecture -> concepts/architecture.md
    • Frontend/backend pattern, embedded browser, deep linking
    • Understand how Zoom loads and communicates with your app
  3. Build your first app -> examples/quick-start.md
    • Complete Express + SDK Hello World
    • ngrok setup for local development
  4. Understand running contexts -> concepts/running-contexts.md
    • Where your app runs (inMeeting, inMainClient, inWebinar, etc.)
    • Context-specific APIs and limitations
  5. Implement OAuth -> examples/in-client-oauth.md
    • In-Client OAuth with PKCE (best UX)
    • Token exchange and storage
  6. Add features -> references/apis.md
    • 100+ SDK methods organized by category
    • Code examples for each
  7. Troubleshoot -> troubleshooting/common-issues.md
    • Quick diagnostics for common problems

如果您是Zoom Apps新手,请按以下顺序操作:
  1. 先运行预检检查 -> RUNBOOK.md
  2. 阅读架构文档 -> concepts/architecture.md
    • 前端/后端模式、嵌入式浏览器、OAuth流程
    • 理解Zoom如何加载并与您的应用通信
  3. 构建您的第一个应用 -> examples/quick-start.md
    • 完整的Express + SDK Hello World应用
    • 本地开发的ngrok设置
  4. 了解运行上下文 -> concepts/running-contexts.md
    • 应用运行位置(inMeeting、inMainClient、inWebinar等)
    • 各上下文专属API及限制
  5. 实现OAuth -> examples/in-client-oauth.md
    • 基于PKCE的客户端内OAuth(最佳体验)
    • 令牌交换及存储
  6. 添加功能 -> references/apis.md
    • 按类别划分的100+ SDK方法
    • 每个方法的代码示例
  7. 故障排除 -> troubleshooting/common-issues.md
    • 常见问题的快速诊断

Documentation Structure

文档结构

zoom-apps-sdk/
├── SKILL.md                           # Main skill overview
├── SKILL.md                           # This file - navigation guide
├── concepts/                          # Core architectural patterns
│   ├── architecture.md               # Frontend/backend, embedded browser, OAuth flow
│   ├── running-contexts.md           # Where your app runs + context-specific APIs
│   └── security.md                   # OWASP headers, CSP, data access layers
├── examples/                          # Complete working code
│   ├── quick-start.md                # Hello World - minimal Express + SDK app
│   ├── in-client-oauth.md            # In-Client OAuth with PKCE
│   ├── layers-immersive.md           # Layers API - immersive mode (custom layouts)
│   ├── layers-camera.md              # Layers API - camera mode (virtual camera)
│   ├── collaborate-mode.md           # Collaborate mode (shared state)
│   ├── guest-mode.md                 # Guest mode (unauthenticated -> authorized)
│   ├── breakout-rooms.md             # Breakout room integration
│   └── app-communication.md          # connect + postMessage between instances
├── troubleshooting/                   # Problem solving guides
│   ├── common-issues.md              # Quick diagnostics, error codes
│   ├── debugging.md                  # Local dev setup, ngrok, browser preview
│   └── migration.md                  # SDK version migration notes
└── references/                        # Reference documentation
    ├── apis.md                        # Complete API reference (100+ methods)
    ├── events.md                      # All SDK events
    ├── layers-api.md                  # Layers API detailed reference
    ├── oauth.md                       # OAuth flows for Zoom Apps
    └── zmail-sdk.md                   # Zoom Mail integration

zoom-apps-sdk/
├── SKILL.md                           # 主技能概述
├── SKILL.md                           # 本文档 - 导航指南
├── concepts/                          # 核心架构模式
│   ├── architecture.md               # 前端/后端、嵌入式浏览器、OAuth流程
│   ├── running-contexts.md           # 应用运行位置 + 各上下文专属API
│   └── security.md                   # OWASP头、CSP、数据访问层
├── examples/                          # 完整可运行代码
│   ├── quick-start.md                # Hello World - 极简Express + SDK应用
│   ├── in-client-oauth.md            # 基于PKCE的客户端内OAuth
│   ├── layers-immersive.md           # Layers API - 沉浸式模式(自定义布局)
│   ├── layers-camera.md              # Layers API - 摄像头模式(虚拟摄像头)
│   ├── collaborate-mode.md           # 协作模式(共享状态)
│   ├── guest-mode.md                 # 访客模式(未认证->已授权)
│   ├── breakout-rooms.md             # 分组讨论室集成
│   └── app-communication.md          # connect + postMessage实例间通信
├── troubleshooting/                   # 问题解决指南
│   ├── common-issues.md              # 快速诊断、错误代码
│   ├── debugging.md                  # 本地开发设置、ngrok、浏览器预览
│   └── migration.md                  # SDK版本迁移说明
└── references/                        # 参考文档
    ├── apis.md                        # 完整API参考(100+方法)
    ├── events.md                      # 所有SDK事件
    ├── layers-api.md                  # Layers API详细参考
    ├── oauth.md                       # Zoom Apps的OAuth流程
    └── zmail-sdk.md                   # Zoom Mail集成

By Use Case

按使用场景分类

I want to build a basic Zoom App

我想构建基础Zoom App

  1. Architecture - Understand the pattern
  2. Quick Start - Build Hello World
  3. In-Client OAuth - Add authorization
  4. Security - Required headers
  1. 架构 - 理解基础模式
  2. 快速开始 - 构建Hello World
  3. 客户端内OAuth - 添加授权
  4. 安全 - 必需的HTTP头

I want immersive video layouts (Layers API)

我想构建沉浸式视频布局(Layers API)

  1. Layers Immersive - Custom video positions
  2. Layers API Reference - All drawing methods
  3. App Communication - Sync layout across participants
  1. Layers沉浸式模式 - 自定义视频位置
  2. Layers API参考 - 所有绘图方法
  3. 应用通信 - 跨参会者同步布局

I want a virtual camera overlay

我想构建虚拟摄像头叠加层

  1. Camera Mode - Camera mode rendering
  2. Layers API Reference - Drawing methods
  1. 摄像头模式 - 摄像头模式渲染
  2. Layers API参考 - 绘图方法

I want real-time collaboration

我想构建实时协作功能

  1. Collaborate Mode - Shared state APIs
  2. App Communication - Instance messaging
  1. 协作模式 - 共享状态API
  2. 应用通信 - 实例间消息传递

I want guest/anonymous access

我想支持访客/匿名访问

  1. Guest Mode - Three authorization states
  2. In-Client OAuth - promptAuthorize flow
  1. 访客模式 - 三种授权状态
  2. 客户端内OAuth - promptAuthorize流程

I want breakout room support

我想支持分组讨论室

  1. Breakout Rooms - Room detection and state sync
  1. 分组讨论室 - 房间检测及状态同步

I want to sync between main client and meeting

我想在主客户端和会议间同步数据

  1. App Communication - connect + postMessage
  2. Running Contexts - Multi-instance behavior
  1. 应用通信 - connect + postMessage
  2. 运行上下文 - 多实例行为

I want serverless deployment

我想进行无服务器部署

  1. Quick Start - Understand the base pattern first
  2. Sample: zoomapps-serverless-vuejs - Firebase pattern
  1. 快速开始 - 先理解基础模式
  2. 示例:zoomapps-serverless-vuejs - Firebase模式

I want to add Zoom Mail integration

我想集成Zoom Mail

  1. Zoom Mail Reference - REST API + mail plugins
  1. Zoom Mail参考 - REST API + 邮件插件

I'm getting errors

我遇到了错误

  1. Common Issues - Quick diagnostic table
  2. Debugging - Local dev setup, DevTools
  3. Migration - Version compatibility

  1. 常见问题 - 快速诊断表
  2. 调试指南 - 本地开发设置、开发者工具
  3. 迁移指南 - 版本兼容性

Most Critical Documents

最关键的文档

1. Architecture (FOUNDATION)

1. 架构(基础)

concepts/architecture.md
Understand how Zoom Apps work: Frontend in embedded browser, backend for OAuth/API, SDK as the bridge. Without this, nothing else makes sense.
concepts/architecture.md
理解Zoom Apps的工作原理:嵌入式浏览器中的前端、用于OAuth/API的后端、作为桥梁的SDK。不理解此内容,其他部分也难以掌握。

2. Quick Start (FIRST APP)

2. 快速开始(第一个应用)

examples/quick-start.md
Complete working code. Get something running before diving into advanced features.
examples/quick-start.md
完整可运行代码。在深入高级功能之前,先让一个简单应用跑起来。

3. Common Issues (MOST COMMON PROBLEMS)

3. 常见问题(最常见问题)

troubleshooting/common-issues.md
90% of Zoom Apps issues are: domain allowlist, global variable conflict, or missing capabilities.

troubleshooting/common-issues.md
90%的Zoom Apps问题都是:域名白名单、全局变量冲突或缺少功能声明。

Key Learnings

核心要点

Critical Discoveries:

关键发现:

  1. Global Variable Conflict is the #1 Gotcha
    • CDN script defines
      window.zoomSdk
      globally
    • let zoomSdk = ...
      causes SyntaxError in Zoom's browser
    • Use
      let sdk = window.zoomSdk
      or NPM import
  2. Domain Allowlist is Non-Negotiable
    • App shows blank panel with zero error if domain not whitelisted
    • Must include your domain AND
      appssdk.zoom.us
      AND any CDN domains
    • ngrok URLs change on restart - must update Marketplace each time
  3. config() Gates Everything
    • Must be called first, must list all capabilities
    • Unlisted capabilities throw errors
    • Check
      unsupportedApis
      for client version compatibility
  4. In-Client OAuth > Web OAuth for UX
    • authorize()
      keeps user in Zoom (no browser redirect)
    • Web redirect only needed for initial Marketplace install
    • Always implement PKCE (code_verifier + code_challenge)
  5. Two App Instances Can Run Simultaneously
    • Main client instance + meeting instance
    • Use
      connect()
      +
      postMessage()
      to sync between them
    • Pre-meeting setup in main client, use in meeting
  6. Camera Mode Has CEF Quirks
    • CEF initialization takes time
    • Draw calls may fail if too early
    • Use retry with exponential backoff
  7. Cookie Settings Matter
    • SameSite=None
      +
      Secure=true
      required
    • Without this, sessions silently fail in embedded browser

  1. 全局变量冲突是头号陷阱
    • CDN脚本全局定义
      window.zoomSdk
    • let zoomSdk = ...
      会在Zoom浏览器中导致SyntaxError
    • 使用
      let sdk = window.zoomSdk
      或NPM导入
  2. 域名白名单必不可少
    • 如果域名未在白名单中,应用会显示空白面板且无任何错误
    • 必须包含您的域名、
      appssdk.zoom.us
      及所有CDN域名
    • ngrok URL重启后会变化 - 每次都必须更新Marketplace
  3. config()控制一切
    • 必须首先调用,必须列出所有功能
    • 未列出的功能会抛出错误
    • 检查
      unsupportedApis
      以确保客户端版本兼容性
  4. 客户端内OAuth的UX优于Web OAuth
    • authorize()
      让用户留在Zoom内(无需浏览器重定向)
    • Web重定向仅在Marketplace首次安装时需要
    • 始终实现PKCE(code_verifier + code_challenge)
  5. 应用可能同时运行两个实例
  • 主客户端实例 + 会议实例
  • 使用
    connect()
    +
    postMessage()
    同步两者
  • 可在主客户端中进行会前设置,在会议中使用
  1. 摄像头模式存在CEF特性问题
    • CEF初始化需要时间
    • 过早调用绘图方法可能失败
    • 使用指数退避重试机制
  2. Cookie设置至关重要
    • 必须设置
      SameSite=None
      +
      Secure=true
    • 否则会话会在嵌入式浏览器中静默失效

Quick Reference

快速参考

"App shows blank panel"

"应用显示空白面板"

-> Domain Allowlist - add domain to Marketplace
-> 域名白名单 - 在Marketplace中添加域名

"SyntaxError: redeclaration"

"SyntaxError: redeclaration"

-> Global Variable - use
let sdk = window.zoomSdk
-> 全局变量 - 使用
let sdk = window.zoomSdk

"config() throws error"

"config()抛出错误"

-> Browser Preview - SDK only works inside Zoom
-> 浏览器预览 - SDK仅在Zoom客户端内工作

"API call fails silently"

"API调用静默失败"

-> OAuth Scopes - add required scopes in Marketplace
-> OAuth权限范围 - 在Marketplace中添加所需权限范围

"How do I implement [feature]?"

"我想实现[功能]怎么办?"

-> API Reference - find the method, check capabilities needed
-> API参考 - 找到对应方法,检查所需功能

"How do I test locally?"

"我如何在本地测试?"

-> Debugging Guide - ngrok + Marketplace config

-> 调试指南 - ngrok + Marketplace配置

Document Version

文档版本

Based on @zoom/appssdk v0.16.x (latest: 0.16.26+)

Happy coding!
Start with Architecture to understand the pattern, then Quick Start to build your first app.
基于**@zoom/appssdk v0.16.x**(最新版本:0.16.26+)

祝您编码愉快!
先从架构开始理解基础模式,然后通过快速开始构建您的第一个应用。