クイックスタート

2 つのブラウザーで共同編集を試し、Client、Transport、Endpoint、Service、Adapter の最小構成をアプリケーションへ組み込みます。

このページには 2 つの進め方があります。まず公式サンプルを動かし、2 つのブラウザーで共同編集の全経路を確認します。その後、最小の Server と Web の構成を読み、自分の Univer アプリケーションに取り込みます。

開始前に環境とバージョンの要件を満たしてください。すべての @univerjs/* と @univerjs-pro/* を、対応する同一リリース群に固定する必要があります。

手順 1:公式サンプルを実行する

実行前の準備

リポジトリは Node.js 24+ と pnpm 10.32.1 を指定しています。node --version と pnpm --version を確認し、ロックファイルを保持してください。pnpm example:* はすべてリポジトリのルートで実行します。ブラウザーとサーバーのビルド、型検査、起動を行うコマンドであり、ホットリロードではありません。変更後は停止して再実行します。

クライアントライセンスがある場合、ビルド前にシェルで UNIVER_LICENSE を設定します。vite.config.ts がブラウザーバンドルに埋め込みます。ビルド済みサーバーの起動時だけ設定しても反映されません。ライセンス設定を参照してください。

Bash
git clone https://github.com/dream-num/univer-collaboration-examples.gitcd univer-collaboration-examplespnpm install --frozen-lockfilepnpm example:quick-start

次を開きます。

text
http://127.0.0.1:3010/?unit=quick-start-sheet

リアルタイム共同編集の確認

  1. 1 つ目のブラウザーウィンドウで URL 全体を開きます。
  2. 別のブラウザープロファイルまたはプライベートウィンドウでも開きます。
  3. どちらかの Sheet でセルを変更します。
  4. 同じ編集がもう一方にも現れることを確認します。

サーバーが 2 つのオンライン Session を作るよう、独立したブラウザーコンテキストを使ってください。同じページ内の編集を見ただけでは Room、ACK、ブロードキャストの経路を検証できません。

成功によって確認できること

text
Univer Collaboration Client  → Node Transport  → UniverCollabEndpoint  → UniverCollabService  → MemoryDatabaseAdapter

2 ブラウザーの同期は、HTTP で Unit を読み込み、使い捨ての Session Ticket で WebSocket Session を開き、同じ Room に参加したことを意味します。Service が OT を実行して新しいリビジョンを確定し、Adapter で保存して、Endpoint が他のメンバーへ配信します。

手順 2:アプリケーションに組み込む

以下は Server と Web の最小構成です。アプリケーション全体の構成は公式クイックスタートを参照してください。

既存の Univer Web アプリケーションでは Runtime、プリセット、UI を維持し、以下の Collaboration Client 設定と Server だけを追加します。空のプロジェクトでは、サンプルの index.html、vite.config.ts、スタイルをアプリケーションの枠としてコピーしてください。

実行可能なファイルから移行する

examples/quick-start をコピーし、package.json、index.html、vite.config.ts、web/styles.css、web/main.ts、server/main.ts を保持します。Express は作業ディレクトリから dist/web を読むため、サンプルディレクトリで build と start を実行します。Vite のライセンス定義と #app の高さも保持してください。以下のコードは構成の説明であり、完全なプロジェクトはこれらのファイルを起点にします。

サンプルのページと /universer-api は同一オリジンです。別のフロントエンドサーバーを使う場合、HTTP と WebSocket Upgrade をプロキシするか、クライアントの 5 つの URL をまとめて変更します。unit はサーバーが作成した ID と一致させます。URL パラメーターだけでは文書は作成されません。サンプルは URL 自動読み込みを無効にし、unit を読み取って loadSheetAsync() で明示的に読み込みます。アプリに組み込む際は共同編集の統合に従い、読み込む前に現在のユーザーを設定してください。

1. 対応する同一バージョンのパッケージ群をインストールする

サーバーには Transport、Endpoint、Service、Database Adapter が 1 つ必要です。ブラウザーには Collaboration Client が必要です。必要なパッケージを入れ、すべての Univer パッケージを同じ厳密なバージョンに固定します。

Bash
pnpm add \  @univerjs-pro/collaboration@1.1.0 \  @univerjs-pro/collaboration-client@1.1.0 \  @univerjs-pro/collaboration-client-ui@1.1.0 \  @univerjs-pro/collaboration-database-memory@1.1.0 \  @univerjs-pro/collaboration-endpoint@1.1.0 \  @univerjs-pro/collaboration-service@1.1.0 \  @univerjs-pro/collaboration-transport-node@1.1.0 \  @univerjs-pro/license@1.1.0 \  @univerjs/core@1.1.0 \  @univerjs/preset-sheets-core@1.1.0 \  @univerjs/presets@1.1.0 \  @univerjs/protocol@1.1.0 \  express react react-dom rxjs

現在の構成と正確なバージョンは、実行可能な公式サンプルのマニフェストを基準にしてください。

2. Service、Endpoint、初期 Unit を作る

UniverCollabService は確定状態を管理する共同編集の中核です。Endpoint がブラウザーのプロトコルを Service に対応付け、Memory Adapter はスナップショット、変更セット、リビジョンを一時保存します。

TypeScript
import { createServer } from "node:http";import express from "express";import type { IWorkbookData } from "@univerjs/core";import { LocaleType } from "@univerjs/core";import { MemoryDatabaseAdapter } from "@univerjs-pro/collaboration-database-memory";import { UniverCollabEndpoint } from "@univerjs-pro/collaboration-endpoint";import { UniverCollabService } from "@univerjs-pro/collaboration-service";import { createNodeTransport } from "@univerjs-pro/collaboration-transport-node";import { ErrorCode, UniverType } from "@univerjs/protocol";const UNIT_ID = "quick-start-sheet";const unitData: IWorkbookData = {  id: UNIT_ID,  rev: 1,  name: "Quick Start Sheet",  appVersion: "",  locale: LocaleType.EN_US,  sheetOrder: ["sheet-1"],  sheets: {    "sheet-1": {      id: "sheet-1",      name: "Sheet 1",      rowCount: 100,      columnCount: 26,      cellData: {},    },  },  styles: {},  resources: [],};const database = new MemoryDatabaseAdapter();const service = new UniverCollabService({ dbAdapter: database });const endpoint = new UniverCollabEndpoint(service);const transport = createNodeTransport();transport.use(async (context, next) => {  context.userID = "demo-user";  await next();});transport.register(endpoint);await service.createUnitFromData(  { type: UniverType.UNIVER_SHEET, data: unitData },  { userID: "demo-user" },);

固定の demo-user は、信頼できる ID が Transport から Endpoint と Service へ流れる仕組みの例です。本番では transport.use() で Cookie、Bearer トークン、セッションを検証してから、安定した業務用 userID を設定します。

3. 認可、HTTP、WebSocket の入口を配置する

現在の Collaboration Client は認可プロトコルを問い合わせます。クイックスタートはこのルートで常に allowed: true を返し、Transport をアプリケーションの HTTP サーバーに接続します。

TypeScript
const app = express();app.post("/universer-api/authz/-/object/-/batch_allowed", express.json(), (request, response) => {  const body = request.body as {    requests: Array<{ unitID: string; objectID: string; actions: unknown[] }>;  };  response.json({    error: { code: ErrorCode.OK, message: "" },    objectActions: body.requests.map((item) => ({      unitID: item.unitID,      objectID: item.objectID,      actions: item.actions.map((action) => ({ action, allowed: true })),    })),  });});app.use(express.static("dist/web"));const server = createServer(app);transport.attach(server);server.listen(3010, "127.0.0.1");

全許可は学習用の簡略化で、セキュリティ境界ではありません。実際のアプリケーションでは HTTP 読み取り、リアルタイム JOIN、変更セット送信、Unit ライフサイクル操作を保護します。必要な範囲は ID と認可を参照してください。

4. ブラウザー Runtime に Collaboration Client を登録する

通常の Web SDK とプリセットを維持し、共同編集プラグインとプロトコル URL を追加します。

TypeScript
import { LocaleType, LogLevel } from "@univerjs/core";import { UniverCollaborationPlugin } from "@univerjs-pro/collaboration";import { UniverCollaborationClientPlugin } from "@univerjs-pro/collaboration-client";import CollaborationClientEnUS from "@univerjs-pro/collaboration-client/locale/en-US";import {  BrowserCollaborationSocketService,  UniverCollaborationClientUIPlugin,} from "@univerjs-pro/collaboration-client-ui";import CollaborationClientUIEnUS from "@univerjs-pro/collaboration-client-ui/locale/en-US";import { UniverLicensePlugin } from "@univerjs-pro/license";import { UniverSheetsCorePreset } from "@univerjs/preset-sheets-core";import UniverPresetSheetsCoreEnUS from "@univerjs/preset-sheets-core/locales/en-US";import { createUniver, defaultTheme, mergeLocales } from "@univerjs/presets";import "@univerjs-pro/collaboration-client/facade";import "@univerjs/preset-sheets-core/lib/index.css";import "@univerjs-pro/collaboration-client-ui/lib/index.css";const httpProtocol = location.protocol === "https:" ? "https" : "http";const wsProtocol = location.protocol === "https:" ? "wss" : "ws";const baseURL = `${httpProtocol}://${location.host}/universer-api`;const unitId = new URLSearchParams(location.search).get("unit");if (!unitId) throw new Error("Open the URL printed by the server; it names the Sheet with ?unit=.");const { univerAPI } = createUniver({  locale: LocaleType.EN_US,  locales: {    [LocaleType.EN_US]: mergeLocales(      UniverPresetSheetsCoreEnUS,      CollaborationClientEnUS,      CollaborationClientUIEnUS,    ),  },  theme: defaultTheme,  logLevel: LogLevel.WARN,  collaboration: true,  presets: [UniverSheetsCorePreset({ container: "app" })],  plugins: [    [UniverLicensePlugin, { license: import.meta.env.UNIVER_LICENSE || undefined }],    UniverCollaborationPlugin,    [      UniverCollaborationClientPlugin,      {        socketService: BrowserCollaborationSocketService,        sendChangesetTimeout: 200,        authzUrl: `${baseURL}/authz`,        snapshotServerUrl: `${baseURL}/snapshot`,        collabSubmitChangesetUrl: `${baseURL}/comb`,        collabWebSocketUrl: `${wsProtocol}://${location.host}/universer-api/comb/connect`,        wsSessionTicketUrl: `${baseURL}/user/session-ticket`,      },    ],    [UniverCollaborationClientUIPlugin, { enableUrlUnitLoader: false }],  ],});const workbook = await univerAPI.getCollaboration().loadSheetAsync(unitId);if (!workbook) throw new Error("Document could not be loaded");

ページには id="app" の要素が必要で、クエリパラメーターから Unit を選びます。

text
/?unit=quick-start-sheet

5. 学習用の設定をアプリケーションの機能に置き換える

学習用設定置き換えるもの
固定の demo-userアプリケーション認証 Middleware と安定したユーザー ID
常に許可する権限チェック読み取り、JOIN、送信、ライフサイクルを覆うサーバー ACL
固定 UnitcreateUnitFromData() を呼ぶ作成 API と製品レコード
Memory AdapterSQLite または契約テスト済みの独自永続化 Adapter

次にデータベースアダプターと ID・認可を実装し、必要に応じて History、Thread Comment、Worktree、Exchange を追加します。実行できる構成はサンプル一覧を参照してください。

初回実行のトラブルシューティング

症状確認点
インストール・ビルド失敗Node.js 24+、指定 pnpm、Univer のバージョン統一
3010 が使用中前のサンプルを停止、または PORT=3011 を設定して両ブラウザーの URL を変更
白画面・静的ファイル不足ビルド完了、サンプルディレクトリで起動、#app の高さ
編集が同期しない完全な URL が同じ、snapshot と session-ticket が成功、/universer-api/comb/connect の WebSocket 接続
再起動で消えるQuick Start はメモリ保存。SQLite サンプルへ進む

このガイドはいかがですか?

© 2026 DreamNum Co., Ltd.