JitWord协同AI文档 v3.0.0
A full-featured collaborative document editor that embeds into any web page via a single CDN script. Built on JitWord Engine, it supports real-time multi-user editing, document import/export, AI writing assistance, and a rich block-based editing experience.
Installation
CDN (Recommended)
Load the required scripts in order. The CDN build externalizes Vue, Arco Design, and heavy IO libraries for a smaller initial payload.
<!-- 1. Vue 3 --> <script src="../cdn/vue.global.prod.js"></script> <!-- 2. Arco Design Vue --> <link rel="stylesheet" href="../cdn/arco.css"> <script src="../cdn/arco-vue.min.js"></script> <script src="../cdn/arco-vue-icon.min.js"></script> <!-- 3. Editor CSS + JS --> <link rel="stylesheet" href="../dist/cdn/jit-word.css"> <script src="../dist/cdn/jit-word.cdn.js"></script>
<script src="../cdn/jit-word.full.js"></script> — bundles everything in one file (~9 MB uncompressed).
CDN Files
| File | Description | Size |
|---|---|---|
cdn/vue.global.prod.js | Vue 3 runtime (global build) | ~155 KB |
cdn/arco-vue.min.js | Arco Design Vue components | ~1.1 MB |
cdn/arco-vue-icon.min.js | Arco Design icon set | ~540 KB |
cdn/arco.css | Arco Design styles | ~460 KB |
cdn/echarts.min.js | ECharts (required for chart blocks) | ~1 MB |
cdn/jit-word.full.js | Full self-contained bundle (all-in-one) | ~6.8 MB |
cdn/px-editor.css | Editor styles | ~1.6 MB |
cdn/jit-word.core.js | Core-only bundle (no Yjs/IO/AI) — use with plugins | ~2 MB |
cdn/jit-word.collab.js | Collab plugin (Yjs + WebSocket) | ~1 MB |
cdn/jit-word.export.js | Export/Import plugin (mammoth / docx / jspdf) | ~2 MB |
cdn/jit-word.ai.js | AI plugin (config + API wrappers) | ~50 KB |
Quick Start
Basic editor (no collaboration)
<!-- Mount target --> <div id="app" style="height: 100vh;"></div> <script> const { JitWord } = window.JitWord const editor = new JitWord({ hold: 'app', // element id or HTMLElement locale: 'zh', // 'zh' | 'en' editable: true, }) </script>
With real-time collaboration
<script> const { JitWord } = window.JitWord const editor = new JitWord({ hold: 'app', currentDocumentId: 'doc-001', user: { id: 'u-001', name: 'Alice', color: '#3b82f6' }, locale: 'zh', }) .use(JitWord.Collab({ wsServer: 'wss://your-domain.com/ws', currentDocumentId: 'doc-001', user: { id: 'u-001', name: 'Alice', color: '#3b82f6' }, })) </script>
Full example with callbacks
const { JitWord } = window.JitWord const editor = new JitWord({ hold: 'app', locale: 'zh', currentDocumentId: 'doc-001', user: { id: 'u-001', name: 'Alice', color: '#4f46e5' }, editable: true, documentTitle: 'My Document', onLoadDocument: async ({ documentId }) => { const doc = await myApi.getDocument(documentId) return doc?.content ? { content: doc.content } : null }, onSaveDocument: async ({ content, documentId }) => { await myApi.saveDocument(documentId, content) }, onUpload: async (file) => { const url = await myApi.uploadFile(file) return url // must return public URL string }, onChange: (content) => { console.log('content changed', content) }, }) // Read content const json = editor.getJSON() // Set content editor.setContent(json) // Cleanup editor.destroy()
Plugin System
JitWord v2 引入了企业级插件架构。无需加载一个庞大的完整包,只需加载最小化的 core,并根据部署需求添加所需插件。这非常适合政府/OA 集成、自定义授权层级以及对包体积敏感的 CI 环境。
Why plugins?
- Pay-per-feature — government clients may want document editing but no AI.
- Smaller bundles — embed a ~2 MB core instead of a 6.8 MB full bundle.
- Independent versioning — ship Collab v2 while keeping Export v1.
- Custom licensing tiers — each plugin can carry its own license check.
MODE 1 — Legacy all-in-one (backward compatible)
<!-- Single script, zero config changes needed --> <script src="cdn/jit-word.full.js"></script> const editor = new JitWord.JitWord({ hold: 'app', wsServer: 'wss://word.jitword.com/ws', currentDocumentId: 'doc-001', })
MODE 2 — Enterprise plugin-based
<!-- Load core (always required) --> <script src="cdn/jit-word.core.js"></script> <!-- Load only the plugins you need --> <script src="cdn/jit-word.collab.js"></script> <!-- optional --> <script src="cdn/jit-word.export.js"></script> <!-- optional --> <script src="cdn/jit-word.ai.js"></script> <!-- optional --> const { JitWord } = window.JitWord // ── Plugin callback configuration (one place for all backend wiring) ── const plugins = { export: {}, pageSettings: {}, watermark: {}, versions: { enableUI: true, onLoadVersions: (docId, page, limit) => myApi.getVersions(docId, page, limit), onCreateVersion: (data) => myApi.createVersion(data), onGetVersion: (docId, versionId) => myApi.getVersion(docId, versionId), onUpdateVersion: (payload) => myApi.updateVersion(payload), onDeleteVersion: (docId, versionId) => myApi.deleteVersion(docId, versionId), }, comment: { enabled: canComment, onLoadComments: (docId) => myApi.getComments(docId), onCreateComment: (data) => myApi.createComment(data), onUpdateComment: (id, data) => myApi.updateComment(id, data), onDeleteComment: (id) => myApi.deleteComment(id), }, mention: { onSearch: async (keyword) => myApi.searchUsers(keyword), onSelect: (user) => console.log('Mentioned:', user), }, share: { enableUI: true, showQRCode: true }, review: { enabled: false }, zoom: { initialZoom: 100, showControls: true }, collab: { wsServer: 'wss://your-domain.com/ws', currentDocumentId: 'doc-001', user: { id: 'u-001', name: 'Alice', color: '#3b82f6' }, enableCursor: true, }, } // ── Register all plugins in one shot ────────────────────────────────── const editor = new JitWord({ hold: 'app', currentDocumentId: 'doc-001' }) .use(JitWord.Export(plugins.export)) .use(JitWord.PageSettings(plugins.pageSettings)) .use(JitWord.Watermark(plugins.watermark)) .use(JitWord.Versions(plugins.versions)) .use(JitWord.Comment(plugins.comment)) .use(JitWord.Mention(plugins.mention)) .use(JitWord.Share(plugins.share)) .use(JitWord.Review(plugins.review)) .use(JitWord.Zoom(plugins.zoom)) .use(JitWord.Collab(plugins.collab))
new JitWord({...}) constructor options work unchanged — the JitWord facade auto-installs plugins when it detects legacy config keys (wsServer, enableAI, etc.).
Collab Plugin Plugin
Adds Yjs real-time collaboration powered by y-websocket. Injects the Collaboration and CollaborationCursor JitWord extensions before the editor mounts.
| Option | Type | Description |
|---|---|---|
wsServer | string | WebSocket server URL, e.g. wss://domain/ws |
currentDocumentId | string | Document ID — room name is auto-derived as doc-{id} |
roomName | string | Override the Yjs room name directly |
user | { name: string; color: string } | Current user for cursor display |
enableCursor | boolean | Show remote user cursors (default: true) |
resetCollabState | boolean | Force fresh Yjs room (use to recover from corrupted state) |
const editor = new JitWord({ hold: 'app' }) .use(JitWord.Collab({ wsServer: 'wss://word.jitword.com/ws', currentDocumentId: 'doc-001', user: { name: 'Alice', color: '#3b82f6' }, }))
Export Plugin Plugin
Adds document import/export capabilities: DOCX, PDF, Markdown, HTML, and JSON. IO libraries are loaded via dynamic import — they are not bundled into the core.
| Option | Type | Description |
|---|---|---|
uploadFn | (file: File) => Promise<string> | Custom upload handler (returns public URL). Falls back to SDK built-in if omitted. |
// Programmatic import after plugin is loaded const result = await editor.importFile('docx', file, { mode: 'replace' }) // Export is available via built-in toolbar or: await editor.exportFile('pdf')
AI Plugin Plugin
Enables AI writing assistance. Patches the editor config with AI feature flags and exposes editor.ai.* API wrappers.
| Option | Type | Description |
|---|---|---|
baseUrl | string | AI API base URL (e.g. /api/v1 or self-hosted model endpoint) |
enableAI | boolean | Show AI writing assistant button (default: true) |
enableAISettings | boolean | Show AI settings drawer (default: true) |
onAiGenerate | (prompt: string) => void | Callback when AI generation is triggered |
aiSettingsConfig | object | Pre-configure provider, model, apiKey, temperature |
const editor = new JitWord({ hold: 'app' }) .use(JitWord.AI({ baseUrl: '/api/v1', enableAI: true, enableAISettings: true, aiSettingsConfig: { provider: 'deepseek', model: 'deepseek-chat', apiKey: 'sk-...', }, })) // AI API wrappers (available after plugin installed) await editor.ai.stream({ prompt: 'Summarize the document' }) const stats = await editor.ai.trialStats()
Comment Plugin Plugin
Adds programmatic comment management (create, list, resolve, update, delete) and wires the built-in comment panel UI via commentsConfig patches. Custom handlers let you replace every SDK call with your own backend.
Exposes editor.comment.* after installation.
| Option | Type | Description |
|---|---|---|
enableUI | boolean | Show the built-in comment panel (default: true) |
onLoadComments | (docId) => Promise<any[]> | Custom handler to fetch comment list |
onCreateComment | (data) => Promise<any> | Custom handler to create a comment |
onUpdateComment | (id, data) => Promise<any> | Custom handler to update a comment |
onDeleteComment | (id, docId) => Promise<any> | Custom handler to delete a comment |
Programmatic API (editor.comment)
| Method | Returns | Description |
|---|---|---|
list(documentId?) | Promise<any[]> | Fetch all comments for the document |
add(content, targetText?, documentId?) | Promise<any> | Create a comment and apply the JitWord mark |
update(id, content, documentId?) | Promise<any> | Edit an existing comment |
delete(id, documentId?) | Promise<void> | Remove a comment and its JitWord mark |
resolve(id, documentId?) | Promise<any> | Mark a comment as resolved |
openPanel(selectedText?) | void | Open the built-in comment panel |
openList() | void | Open the comment list sidebar |
const editor = new JitWord({ hold: 'app', currentDocumentId: 'doc-001' }) .use(JitWord.Comment({ onLoadComments: (docId) => myApi.getComments(docId), onCreateComment: (data) => myApi.createComment(data), onDeleteComment: (id, docId) => myApi.deleteComment(id), })) // After mount: await editor.comment.add('Please review this paragraph', 'selected text') const list = await editor.comment.list() editor.comment.openPanel()
Versions Plugin Plugin
Adds version history management with optional auto-save. The built-in VersionManager UI is enabled; custom backend handlers can override every SDK call. Exposes editor.versions.*.
| Option | Type | Description |
|---|---|---|
enableUI | boolean | Show the built-in version panel (default: true) |
autoSaveInterval | number | Auto-save interval in ms (e.g. 60000). Disabled by default. |
autoSaveTitle | string | Title prefix for auto-saved versions. Default: 'Auto-save' |
onLoadVersions | (docId, page, limit) => Promise<{versions, total}> | Custom handler to list versions |
onCreateVersion | (data) => Promise<any> | Custom handler to create a version |
onGetVersion | (docId, versionId) => Promise<any> | Custom handler to fetch a single version |
onUpdateVersion | (payload) => Promise<any> | Custom handler to rename/update a version |
onDeleteVersion | (docId, versionId) => Promise<any> | Custom handler to delete a version |
Programmatic API (editor.versions)
| Method | Returns | Description |
|---|---|---|
list(page?, limit?, documentId?) | Promise<{versions, total}> | Fetch paginated version list |
create(title?, description?, documentId?) | Promise<any> | Create a manual version checkpoint |
get(versionId, documentId?) | Promise<any> | Fetch a single version for preview |
restore(versionId, documentId?) | Promise<void> | Restore content from a version (calls setContent()) |
update(versionId, data, documentId?) | Promise<any> | Rename or update a version's metadata |
delete(versionId, documentId?) | Promise<void> | Delete a version |
compare(vId1, vId2, documentId?) | Promise<any> | Get a diff between two versions |
openPanel() | void | Open the version history panel |
const editor = new JitWord({ hold: 'app' }) .use(JitWord.Versions({ enableUI: true, autoSaveInterval: 60000, // auto-save every 60 s autoSaveTitle: 'Auto', })) await editor.versions.create('Before major edit') await editor.versions.restore('ver-xyz') editor.versions.openPanel()
Watermark Plugin Plugin
Adds a tiled watermark overlay driven by pageSettings.watermark. The watermark is also included in PDF/DOCX exports. Exposes editor.watermark.*.
| Option | Type | Description |
|---|---|---|
text | string | Watermark label text |
opacity | number | Opacity 0–1. Default: 0.12 |
color | string | CSS color. Default: '#a0aec0' |
angle | number | Rotation in degrees. Default: -30 |
fontSize | number | Font size in px. Default: 20 |
gap | number | Tile gap in px. Default: 160 |
enabled | boolean | Enable watermark on init (default: true when text is set) |
Programmatic API (editor.watermark)
| Method | Description |
|---|---|
set(config) | Apply a new watermark config (replaces current) |
update(partial) | Merge a partial config into the current watermark |
remove() | Remove the watermark overlay |
get() | Return the current WatermarkConfig or null |
isEnabled() | Returns true if watermark is currently visible |
.use(JitWord.Watermark({ text: 'CONFIDENTIAL', opacity: 0.15 })) // Runtime updates: editor.watermark.update({ text: 'DRAFT' }) editor.watermark.remove() editor.watermark.set({ text: 'INTERNAL', color: '#ef4444', angle: -45 })
PageSettings Plugin Plugin
Adds programmatic page layout control (paper size, margins, orientation, line spacing). The built-in PageSettings modal is wired via config patches; custom load/save handlers support any backend. Exposes editor.pageSettings.*.
| Option | Type | Description |
|---|---|---|
initialSettings | PageSettingsConfig | Page settings applied on init (A4 portrait by default) |
onGetPageSettings | (docId) => Promise<PageSettingsConfig> | Custom handler to load settings from backend |
onUpdatePageSettings | (docId, settings) => Promise<any> | Custom handler to persist settings to backend |
PageSettingsConfig fields
| Field | Default | Description |
|---|---|---|
paperSize | 'A4' | Paper size. Common: 'A4', 'A3', 'Letter', 'Legal' |
orientation | 'portrait' | 'portrait' or 'landscape' |
margins | 25.4 / 31.8 mm | Page margins object: { top, bottom, left, right, header, footer } in mm |
lineHeight | 1.5 | Line height multiplier |
fontFamily | — | Default font family |
fontSize | — | Default font size in pt |
Programmatic API (editor.pageSettings)
| Method | Description |
|---|---|
get() | Return current PageSettingsConfig |
fetch(documentId?) | Load settings from the backend and apply them |
apply(settings, persist?) | Apply settings (and optionally persist to backend) |
reset(persist?) | Reset to default A4 portrait settings |
set(key, value, persist?) | Update a single setting key |
openPanel() | Open the built-in page settings modal |
.use(JitWord.PageSettings({ initialSettings: { paperSize: 'A4', orientation: 'portrait' }, onUpdatePageSettings: (docId, s) => myApi.savePageSettings(docId, s), })) // Switch to A3 landscape at runtime: await editor.pageSettings.apply({ paperSize: 'A3', orientation: 'landscape' }) editor.pageSettings.openPanel()
Mention Plugin Plugin
Adds @mention support by wiring the JitWord Mention extension (already bundled in collabBase: 'notion') with a user-list provider. Exposes editor.mention.*.
| Option | Type | Description |
|---|---|---|
users | MentionUser[] | Static list of mentionable users |
onSearch | (keyword: string) => Promise<MentionUser[]> | Async lookup by keyword (overrides static users) |
onSelect | (user: MentionUser) => void | Callback when a user is mentioned |
maxSuggestions | number | Max items in dropdown. Default: 5 |
MentionUser shape
| Field | Type | Description |
|---|---|---|
id | string | Unique user ID |
label | string | Display name shown in dropdown and inserted text |
avatar | string | Optional avatar URL |
Programmatic API (editor.mention)
| Method | Description |
|---|---|
setUsers(users) | Replace the static user list |
addUsers(users) | Append users to the existing list |
getUsers() | Return current user list |
insert(label, id) | Programmatically insert a mention at cursor |
.use(JitWord.Mention({ users: [ { id: 'u1', label: 'Alice', avatar: 'https://i.pravatar.cc/32?u=1' }, { id: 'u2', label: 'Bob' }, ], // Or use async lookup: onSearch: async (keyword) => { const res = await fetch(`/api/users?q=` + keyword) return res.json() }, onSelect: (user) => console.log('Mentioned:', user), })) editor.mention.insert('Alice', 'u1')
Share Plugin Plugin
Adds document sharing and permission management. The built-in ShareDocumentDialog is wired via config patches; custom URL generators or permission handlers support white-label deployments. Exposes editor.share.*.
| Option | Type | Description |
|---|---|---|
enableUI | boolean | Show the built-in share dialog button (default: true) |
showQRCode | boolean | Include QR code in share dialog (default: false) |
getShareUrl | () => string | Returns the editable share URL. Defaults to window.location.href |
getReadOnlyUrl | () => string | Returns the read-only URL. Defaults to <origin>/read/<docId> |
onSetPermission | (docId, permission) => Promise<any> | Custom handler to change document permission |
onShare | (info) => void | Callback when the share dialog is opened |
Programmatic API (editor.share)
| Method | Description |
|---|---|
open() | Open the share dialog |
getShareUrl() | Return the current editable share URL |
getReadOnlyUrl(documentId?) | Return the read-only URL |
setPermission(permission, documentId?) | Update document permission: 'read' | 'edit' | 'private' |
copyUrl(type?) | Copy edit or read URL to clipboard (type: 'edit' | 'read') |
.use(JitWord.Share({ enableUI: true, showQRCode: true, getShareUrl: () => `https://myapp.com/docs/` + docId, getReadOnlyUrl: () => `https://myapp.com/docs/` + docId + '?mode=read', onSetPermission: (docId, perm) => myApi.setPermission(docId, perm), })) editor.share.open() await editor.share.setPermission('read') await editor.share.copyUrl('read')
Review Plugin Plugin
Adds track-changes / review mode for document audit workflows (government, enterprise, legal). When active, every edit is wrapped as a tracked change that can be accepted or rejected individually or in bulk. Exposes editor.review.*.
| Option | Type | Description |
|---|---|---|
enabled | boolean | Start in review mode immediately (default: false) |
author | { name: string; color?: string } | Author identity shown on tracked changes |
enableEditHistory | boolean | Enable the edit history audit panel (default: true) |
onChange | (active: boolean) => void | Fires when review mode is toggled |
Programmatic API (editor.review)
| Method | Returns | Description |
|---|---|---|
enable() | void | Enter review/track-changes mode |
disable() | void | Exit review mode |
toggle() | boolean | Toggle mode, returns new state |
isActive() | boolean | Whether review mode is currently on |
acceptAll() | void | Accept all pending tracked changes |
rejectAll() | void | Reject all pending tracked changes |
setAuthor(author) | void | Update the review author identity at runtime |
openHistory() | void | Open the edit history audit panel |
.use(JitWord.Review({ enabled: false, author: { name: 'Alice', color: '#f87171' }, onChange: (active) => console.log('Review:', active ? 'ON' : 'OFF'), })) editor.review.enable() editor.review.acceptAll() console.log(editor.review.isActive()) // false after acceptAll
Zoom Plugin Plugin
Adds programmatic zoom and view-mode control (Web view / Word page view). The built-in ZoomControls UI can be shown or hidden; integrators can render their own controls using the API. Exposes editor.zoom.*.
| Option | Type | Description |
|---|---|---|
initialZoom | number | Initial zoom level in percent. Default: 100 |
minZoom | number | Minimum zoom percent. Default: 50 |
maxZoom | number | Maximum zoom percent. Default: 200 |
initialView | 'web' | 'word' | Initial view mode. Default: 'web' |
showControls | boolean | Show the built-in zoom controls. Default: true |
onZoomChange | (level: number) => void | Fires on every zoom level change |
onViewChange | (view: 'web' | 'word') => void | Fires on view mode switch |
Programmatic API (editor.zoom)
| Method | Returns | Description |
|---|---|---|
set(level) | void | Set zoom to an exact percentage (clamped to min/max) |
get() | number | Return current zoom level |
in(step?) | void | Zoom in by step percent (default: 10) |
out(step?) | void | Zoom out by step percent (default: 10) |
reset() | void | Reset zoom to 100% |
setView(view) | void | Switch to 'web' or 'word' view mode |
toggleView() | void | Toggle between web and word view |
getView() | 'web' | 'word' | Return current view mode |
setControlsVisible(visible) | void | Show or hide the built-in zoom controls |
.use(JitWord.Zoom({ initialZoom: 100, showControls: true, onZoomChange: (lvl) => console.log('zoom:', lvl + '%'), onViewChange: (view) => console.log('view:', view), })) editor.zoom.set(150) editor.zoom.in(10) editor.zoom.setView('word') console.log(editor.zoom.get()) // 160 editor.zoom.reset()
Constructor
Creates and mounts the editor into the specified container element. For collaboration mode, initialization is asynchronous — the editor waits for Yjs sync before rendering.
Config Options
Core
| Option | Type | Default | Description |
|---|---|---|---|
hold required | string | HTMLElement | — | Target container. String = element ID. |
locale | 'zh' | 'en' | 'zh' | UI language. |
theme | 'light' | 'dark' | 'light' | Color theme. |
editable | boolean | true | Whether the document is editable. |
collabBase | 'notion' | 'basic' | 'minimal' | 'notion' | Extension preset. 'notion' includes all blocks; 'basic' is lighter; 'minimal' is text-only. |
placeholder | string | '请输入文档内容...' | Editor placeholder text. |
baseApiUrl | string | — | Base URL for backend API calls (document save, AI, etc.). |
documentTitle | string | 'Loading...' | Initial document title shown in the title bar. Set this to avoid the default "Loading..." state. |
Collaboration
| Option | Type | Default | Description |
|---|---|---|---|
enableCollaboration | boolean | true | Enable Yjs real-time collaboration. |
wsServer | string | — | WebSocket server URL. e.g. wss://domain/ws |
currentDocumentId | string | — | Document ID. Used as the Yjs room name (doc-{id}). |
roomName | string | auto | Override the Yjs room name directly. |
user | { name: string; color: string } | Anonymous | Current user identity for collaboration cursors. |
enableCollaborationCursor | boolean | true | Show remote user cursors. |
resetCollabState | boolean | false | Force a fresh room (appends timestamp to roomName). Use to recover from corrupted Yjs state. |
UI Visibility
| Option | Type | Default | Description |
|---|---|---|---|
hideToc | boolean | false | Hide the table of contents sidebar. |
hideFooter | boolean | false | Hide the footer bar. |
showOnlineUsers | boolean | true | Show online collaborator avatars. |
showRightToolbar | boolean | true | Show the floating right toolbar. |
showScrollNav | boolean | true | Show scroll navigation. |
enableAI | boolean | true | Show AI writing assistant. |
enableAISettings | boolean | true | Show the AI settings drawer (API key, model, provider). |
enableVersions | boolean | true | Show version history feature. |
enableShare | boolean | false | Show share button and dialog. |
enableAuth | boolean | false | Enable built-in authentication flow. |
enableReadMode | boolean | true | Show read-mode toggle. |
enableDocumentList | boolean | true | Show document list panel. |
AI Configuration (aiConfig)
Pass an aiConfig object to pre-configure the AI provider. All fields are optional — users can also configure these via the built-in AI Settings drawer.
| Field | Type | Default | Description |
|---|---|---|---|
provider | 'deepseek' | 'kimi' | 'glm' | 'custom' | — | AI provider preset. Use 'custom' with baseUrl for self-hosted models. |
model | string | — | Model identifier, e.g. 'deepseek-chat', 'moonshot-v1-8k'. |
apiKey | string | — | API key for the selected provider. Stored in localStorage if set via UI. |
baseUrl | string | — | Custom API base URL. Required when provider: 'custom'. |
temperature | number | 0.7 | Sampling temperature (0–2). Higher = more creative. |
const editor = new JitWord.JitWord({ hold: 'app', enableAI: true, enableAISettings: true, aiConfig: { provider: 'deepseek', model: 'deepseek-chat', apiKey: 'sk-...', temperature: 0.7 } })
Version Config (versionConfig)
Override the built-in version CRUD handlers. When not provided, versions are managed automatically via baseApiUrl.
| Field | Type | Description |
|---|---|---|
onLoadVersions | (docId, page, limit) => Promise<{versions, total}> | Fetch version list. Return { versions: [...], total: number }. |
onCreateVersion | (data) => Promise<void> | Create a version. data includes content, title, description, isAutoSave, author. |
onUpdateVersion | (docId, versionId, data) => Promise<void> | Rename or update a version. |
onDeleteVersion | (docId, versionId) => Promise<void> | Delete a version. |
onGetVersion | (docId, versionId) => Promise<object> | Fetch a single version for preview/restore. |
Callbacks
| Option | Type | Description |
|---|---|---|
onLoadDocument | ({ documentId }) => Promise<{ content: object } | null> | Load document content from your backend. Return { content } or null to fall back to defaultValue. |
onSaveDocument | ({ content, documentId }) => Promise<void> | Save document content to your backend (triggered by toolbar save button). |
onSave | ({ content, currentDocumentId }) => void | Fires on keyboard save (Ctrl+S / ⌘S). |
onChange | (content: object) => void | Fires on every content change. |
onUpload | (file: File) => Promise<string> | Custom image/file upload handler. Must return the public URL string. |
onDocumentTitleChange | ({ documentId, title }) => Promise<void> | Fires when the user edits the document title in the title bar. |
onEditorReady | (editor: Editor) => void | Fires once the editor is mounted. Receives the raw JitWord editor instance. |
onEditorDestroy | () => void | Fires when the editor is destroyed. |
Document List Config (docsConfig)
Wire the built-in "文件" (File) button document list panel to your backend. Requires enableDocumentList: true.
| Field | Type | Description |
|---|---|---|
autoLoad | boolean | When false (recommended), use onLoadDocuments callback. When true, SDK calls built-in fetcher (requires baseApiUrl). |
title | string | Panel header title. Default: '我的文档' |
createText | string | Create button label. |
emptyText | string | Empty state text. |
onLoadDocuments | () => Promise<DocItem[]> | Fetch document list. Each item: { id, name, updatedAt } |
onCreateDocument | (name) => Promise<{ id, name }> | Create a new document and return it. |
onDeleteDocument | (docId) => Promise<void> | Delete a document by ID. |
onRenameDocument | (docId, newName) => Promise<void> | Rename a document. |
onSelectDocument | (docId) => void | Fires when a document is selected. Use editor.setCurrentDocumentId(docId) here. |
Content API
getJSON() method
Returns the current document as a JitWord/ProseMirror JSON object.
getHTML() method
Returns the current document as an HTML string.
setContent(data, emitUpdate?) method
Replace the entire document content. data can be a JSON object (from getJSON()) or an HTML string.
setData(data) method
Alias for setContent().
setEditable(editable) method
Toggle the editor between editable and read-only mode at runtime.
getEditor() method
Returns the raw JitWord Editor instance for advanced low-level access.
setCurrentDocumentId(documentId) method
Switch to a different document without re-creating the editor. In collaboration mode, tears down the old Yjs provider, creates a new one for doc-{documentId}, and waits for sync before remounting.
// Switch document in a multi-document app editor.setCurrentDocumentId('doc-002')
Element API
Programmatically manage document blocks. Every block has a stable id attribute.
insert(index?, element) method
// Append a heading editor.insert({ type: 'heading', data: { level: 1, text: 'Hello World' } }) // Insert a paragraph at position 2 editor.insert(2, { type: 'paragraph', data: { text: 'Inserted text' } }) // Insert an image editor.insert({ type: 'image', data: { src: 'https://example.com/img.png', alt: 'photo' } })
getElementById(id) method
Find a block by its ID.
updateElement(id, patch) method
editor.updateElement('abc123', { data: { text: 'Updated text' } })
deleteElementById(id) method
Delete a block by ID.
Import / Export
docx, mammoth, jsPDF, etc.). In CDN mode these are externalized — load them from CDN before calling these methods if needed.
importFile(type, file, options?) method
| type | Description |
|---|---|
'docx' | Import Word document (.docx) |
'md' | Import Markdown file |
'html' | Import HTML file |
'json' | Import editor JSON format |
const input = document.createElement('input') input.type = 'file' input.accept = '.docx' input.onchange = async (e) => { const file = e.target.files[0] const result = await editor.importFile('docx', file, { mode: 'replace' }) console.log(result.success, result.warnings) } input.click()
Export (programmatic)
Export buttons are built into the editor toolbar (PDF, Word, Markdown, HTML). For programmatic export use editor.exportFile():
// Trigger download directly await editor.exportFile('docx', { filename: 'my-doc.docx' }) await editor.exportFile('md', { filename: 'my-doc.md' }) // Get PDF as Blob (no auto-download): const blob = await editor.exportFile('pdf', { autoDownload: false, filename: 'my-doc.pdf' }) console.log(blob.size, 'bytes')
Lifecycle
destroy() method
Tear down the editor completely: disconnects Yjs WebSocket, destroys Y.Doc, destroys JitWord editor, and unmounts the Vue app. Always call this before removing the container from the DOM.
// In a SPA router hook onBeforeUnmount(() => { editor.destroy() })
Collaboration
Real-time collaboration is powered by Yjs + y-websocket. Each document maps to a Yjs room named doc-{documentId}.
const { JitWord } = window.JitWord const editor = new JitWord({ hold: 'app', currentDocumentId: 'doc-001', user: { id: 'u-001', name: 'Bob', color: '#059669' }, // Auto-disconnects on destroy() }) .use(JitWord.Collab({ wsServer: 'wss://your-domain.com/ws', currentDocumentId: 'doc-001', user: { id: 'u-001', name: 'Bob', color: '#059669' }, enableCursor: true, }))
The collaboration WebSocket endpoint is provided by the backend server. The default backend uses the /ws path. Multiple users connecting with the same currentDocumentId will automatically share the same document.
Switching documents at runtime
// Switch to a different document — rebuilds Yjs connection editor.setCurrentDocumentId('doc-002')
Version & History API
When enableVersions: true and baseApiUrl is set, version history is fully managed automatically. You can also call the backend REST API directly via JitWord.JitWordSDK.
REST API (via JitWordSDK.versions)
const { JitWordSDK } = window.JitWord // Initialize once with your backend base URL JitWordSDK.init({ baseUrl: 'https://your-domain.com/api/v1' }) // List versions (paginated) const { versions, total } = await JitWordSDK.versions.getVersions('doc-001', 1, 20) // Create a manual checkpoint await JitWordSDK.versions.createVersion('doc-001', { content: editor.getJSON(), title: 'Before major edit', isAutoSave: false }) // Get a single version for preview const ver = await JitWordSDK.versions.getVersion('doc-001', 'ver-xyz') // Restore by pushing the old content back editor.setContent(ver.data.content) // Rename a version await JitWordSDK.versions.updateVersion('doc-001', 'ver-xyz', { title: 'Renamed' }) // Delete a version await JitWordSDK.versions.deleteVersion('doc-001', 'ver-xyz') // Compare two versions (returns diff) const diff = await JitWordSDK.versions.compareVersions('doc-001', 'ver-a', 'ver-b')
Custom version handlers (versionConfig)
For custom backends, pass versionConfig to the constructor (see Config Options). The built-in UI will call your handlers instead of the default REST SDK.
File Upload
Provide an onUpload callback to handle image/attachment uploads. The function receives a File and must return a Promise resolving to the public URL.
const { JitWord } = window.JitWord const editor = new JitWord({ hold: 'app', onUpload: async (file) => { const form = new FormData() form.append('file', file) const res = await fetch('/api/upload', { method: 'POST', body: form }) const { url } = await res.json() return url // must return the public URL string } })
Events / Callbacks
| Option | Signature | Description |
|---|---|---|
onLoadDocument | ({ documentId }) => Promise<{ content } | null> | Load document content. Return null to use defaultValue. |
onSaveDocument | ({ content, documentId }) => Promise<void> | Save triggered by toolbar save button. |
onSave | ({ content, currentDocumentId }) => void | Fires when the user presses Ctrl+S / ⌘S. |
onChange | (content: object) => void | Fires on every content change with the full JSON snapshot. |
onUpload | (file: File) => Promise<string> | Custom image/file upload. Must return public URL. |
onDocumentTitleChange | ({ documentId, title }) => Promise<void> | Fires when user edits the document title. |
onEditorReady | (editor: Editor) => void | Fires once the editor is mounted and ready. |
onEditorDestroy | () => void | Fires when the editor is destroyed. |
i18n
Pass locale: 'zh' or locale: 'en' in the constructor. The language is applied at initialization and cannot be changed at runtime without recreating the instance.
const { JitWord } = window.JitWord const editor = new JitWord({ hold: 'app', locale: 'en', // English UI })
Element Types
Used with the Element API. Each type corresponds to a document block.
| type | data fields | Description |
|---|---|---|
paragraph | text | Plain text paragraph |
heading | text, level (1-6) | Section heading |
image | src, alt, width | Inline or block image |
attachment | url, name, size | File attachment |
divider | — | Horizontal rule |
bulletList | items: string[] | Unordered list |
orderedList | items: string[] | Ordered list |
columns | columns: SDKElement[][] | Multi-column layout |
table | rows, cols, cells | Table block |
chart | chartType, data, options | ECharts chart |
mindmap | data (MindElixir format) | Mind map |
mermaid | code | Mermaid diagram |
flowchart | nodes, edges | Interactive flowchart (vue-flow) |
Build Formats
| Script | Output | Description |
|---|---|---|
npm run build | dist/index.js + .cjs | ESM + CJS library (for npm/bundler use) |
npm run build:umd | dist/jit-word.umd.js | UMD bundle (externalizes Vue/Arco) |
npm run build:full | cdn/jit-word.full.js | Full self-contained bundle (all deps bundled, ~6.8 MB) |
npm run build:core | cdn/jit-word.core.js | Core-only bundle (no Yjs/IO/AI, ~2 MB) |
npm run build:plugin:collab | cdn/jit-word.collab.js | Collab plugin (Yjs + WebSocket) |
npm run build:plugin:export | cdn/jit-word.export.js | Export/Import plugin (mammoth / docx / jspdf) |
npm run build:plugin:ai | cdn/jit-word.ai.js | AI plugin (config + API wrappers) |
npm run build:plugins | all 3 plugins | Build collab + export + ai plugins in sequence |
npm run build:all | all of the above | Build all formats at once |