JSPM

@jitword/collab-editor

1.0.4
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 1
  • Score
    100M100P100Q83655F
  • License MIT

A comprehensive collaborative editor SDK with real-time collaboration features. Drop it into any Vue application and get a full-featured editor with Notion-like experience.

Package Exports

  • @jitword/collab-editor
  • @jitword/collab-editor/dist/style.css

Readme

@jitword/collab-editor

A comprehensive, production-ready collaborative editor SDK built with Vue 3 and Tiptap. Drop it into any Vue application and get a full-featured editor with real-time collaboration support.

npm version License: MIT

✨ Features

  • 📝 Rich Text Editing - Full WYSIWYG editor with Notion-like experience
  • 👥 Real-time Collaboration - Built-in collaborative editing support
  • 🎨 Categorized Toolbar - Organized tools (Home, Insert, View, Export)
  • 📋 Table of Contents - Auto-generated document outline with smooth scrolling
  • 📊 Word Count - Real-time paragraph and character statistics
  • 🤖 AI Integration Ready - Events for AI writing, version control, and sharing
  • ⌨️ Keyboard Shortcuts - Command+S (Mac) / Ctrl+S (Windows) to save
  • 📱 Responsive Design - Works seamlessly on desktop, tablet, and mobile
  • 🎯 Highly Configurable - Control every feature via props
  • 🔌 Event-Driven - Emit events for business logic integration
  • 💅 Beautiful UI - Based on Arco Design system
  • ✨ Built-in Modals - Share, AI Writer, and Document Management modals included
  • 🚀 Out-of-the-Box - Share and Read Mode work automatically

🏗️ Architecture Principles

🔐 Security: API keys and authentication stay in your code
🔌 Flexible: Supports any collaboration backend (Yjs, Socket.io, custom, etc.)
📦 Lightweight: SDK doesn't include specific network libraries
🎯 Clear Responsibilities: SDK handles UI, you handle data

📦 Installation

# Using npm
npm install @jitword/collab-editor vue

# Using yarn
yarn add @jitword/collab-editor vue

# Using pnpm
pnpm add @jitword/collab-editor vue

Note: @arco-design/web-vue is a peer dependency and will be installed automatically. All collaboration dependencies (yjs, y-websocket, @tiptap/extension-collaboration) are bundled in the package.

🚀 Quick Start

1. Import Styles and Register Components

// main.js
import { createApp } from 'vue'
import ArcoVue from '@arco-design/web-vue'
import '@arco-design/web-vue/dist/arco.css'
import '@jitword/collab-editor/dist/style.css'
import App from './App.vue'

const app = createApp(App)
app.use(ArcoVue)
app.mount('#app')

2. Basic Usage (Out-of-the-Box)

The simplest way to use the editor with built-in features:

<template>
  <CollabEditorApp
    v-model="content"
    :config="editorConfig"
    :onlineUsers="onlineUsers"
    :currentDocumentId="currentDocId"
    @ai-generate="handleAIGenerate"
    @editor-ready="handleEditorReady"
    style="height: 100vh;"
  />
</template>

<script setup>
import { ref } from 'vue'
import { CollabEditorApp, NotionKit } from '@jitword/collab-editor'

const content = ref({
  type: 'doc',
  content: [
    {
      type: 'paragraph',
      content: [{ type: 'text', text: 'Start editing...' }]
    }
  ]
})

const onlineUsers = ref([
  { id: 1, name: 'Alice', color: '3b82f6' },
  { id: 2, name: 'Bob', color: '10b981' }
])

const currentDocId = ref('doc-123')

const editorConfig = {
  appTitle: 'My Collaborative Editor',
  documentTitle: 'Untitled Document',
  roomName: 'my-room', // For share modal display
  enableAI: true,
  enableShare: true,
  enableReadMode: true,
  enableDocumentList: true,
  showOnlineUsers: true,
  extensions: [NotionKit]
}

// Handle AI generation (only business logic needed)
const handleAIGenerate = async ({ prompt, editor }) => {
  // Call your AI API
  const result = await callYourAIService(prompt)
  // Insert into editor
  editor.commands.insertContent(result)
}

const handleEditorReady = (editor) => {
  console.log('Editor ready:', editor)
}
</script>

What you get automatically:

  • ✅ Share button → Opens built-in share modal with QR code
  • ✅ AI button → Opens built-in AI writer modal
  • ✅ Read Mode button → Opens /read/{docId} in new tab
  • ✅ Online users display in header
  • ✅ All UI components styled and ready

📚 API Reference

Props

v-model (Object | String)

The editor content. Can be ProseMirror JSON or HTML string.

const content = ref({
  type: 'doc',
  content: [/* ... */]
})

config (Object)

Editor configuration object.

Property Type Default Description
appTitle String 'JitWord 协同文档' Application title (desktop)
appTitleShort String 'JitWord' Short title (mobile)
documentTitle String '未命名文档' Current document title
enableAI Boolean true Show AI writing button
enableVersions Boolean true Show version history button
enableShare Boolean true Show share button
enableReadMode Boolean true Show read mode button
enableAISettings Boolean true Show AI settings button
enableDocumentList Boolean false Show document list button
enableCreateDocument Boolean false Show create document button
createDocumentTooltip String '新建文档' Tooltip for create button
showOnlineUsers Boolean true Display online users
hideToc Boolean false Hide table of contents
hideFooter Boolean false Hide footer (word count)
hideHeader Boolean false Hide header bar
hideToolbar Boolean false Hide formatting toolbar
hideBubbleMenu Boolean false Hide bubble menu
editable Boolean true Allow editing
locale String 'en' Editor locale
theme String 'light' Editor theme
isMobile Boolean false Mobile mode
isTablet Boolean false Tablet mode
aiWriterBusy Boolean false AI writer loading state
extensions Array [NotionKit] Tiptap extensions
uploadFn Function null Custom file upload handler
defaultCategory String 'home' Default toolbar category
pageWidth Number 210 Page width (mm)
pageHeight Number 297 Page height (mm)
marginTop Number 25.4 Top margin (mm)
marginRight Number 31.7 Right margin (mm)
marginBottom Number 25.4 Bottom margin (mm)
marginLeft Number 31.7 Left margin (mm)
readMode Boolean false Enable read-only mode (hides toolbar, shows simple header)
readModeBadgeText String 'Read-only Mode' Badge text shown in read mode

Built-in Modal Configuration:

Property Type Default Description
useBuiltinModals Boolean true Enable all built-in modals
roomName String '' Room name (shown in share modal)
shareConfig Object {} Share modal configuration (see below)
aiConfig Object {} AI modal configuration (see below)
aiSettingsConfig Object {} AI Settings modal configuration (see below)
versionConfig Object {} Version History modal configuration (see below)
docsConfig Object {} Document drawer configuration (see below)
getReadModeUrl Function null Custom read mode URL generator
onReadModeClick Function null Custom read mode handler

onlineUsers (Array)

Array of online users for collaboration display.

const onlineUsers = ref([
  { id: 1, name: 'Alice', color: '3b82f6' }, // No # prefix
  { id: 2, name: 'Bob', color: '10b981' }
])

documents (Array)

Array of documents for built-in document drawer.

const documents = ref([
  { id: 'doc-1', name: 'My Document', updatedAt: Date.now() },
  { id: 'doc-2', name: 'Another Doc', updatedAt: Date.now() - 3600000 }
])

currentDocumentId (String)

Current document ID (required for read mode and document drawer).

const currentDocumentId = ref('doc-123')

isTrashView (Boolean)

Whether document drawer is showing trash view.

documentsLoading (Boolean)

Loading state for document drawer.

Events

Editor Events

Event Payload Description
update:modelValue content Emitted when content changes
editor-ready editor Emitted when editor is initialized

Header Button Events

Event Payload Description
ai-click { editor } AI writing button clicked (custom mode)
version-click { editor } Version history button clicked
share-click { editor } Share button clicked (custom mode)
ai-settings-click { editor } AI settings button clicked
read-mode-click { editor } Read mode button clicked (custom mode)
document-list-click { editor } Document list button clicked (custom mode)
create-document-click { editor } Create document button clicked
mobile-menu-select value Mobile menu item selected

Built-in Modal Events

Event Payload Description
ai-generate { prompt, editor } User requested AI generation
toggle-trash - Toggle trash view in document drawer
select-document docId Document selected from drawer
create-document - Create new document requested
delete-document docId Soft delete document (move to trash)
restore-document docId Restore document from trash
permanent-delete-document docId Permanently delete document
rename-document docId, newName, onSuccess Rename document
save { editor, content, currentDocumentId } Save triggered by keyboard shortcut (Cmd+S / Ctrl+S)
version-restore content Version restored, update editor content
version-create { documentId, content, title, description, isAutoSave, author } Version created successfully
version-update { documentId, versionId, title, description } Version metadata updated
version-delete { documentId, versionId, version } Version deleted
version-preview { documentId, versionId, version, content } Version previewed

Slots

#headerLeftActions

Add custom actions to the left side of the header (after built-in buttons).

<CollabEditorApp>
  <template #headerLeftActions>
    <a-button @click="customAction">Custom</a-button>
  </template>
</CollabEditorApp>

#headerMiddleActions

Add custom actions to the middle of the header (after version button).

#headerMobileMenuItems

Add custom items to the mobile dropdown menu.

#modals

Add custom modal components with access to editor and config.

<CollabEditorApp>
  <template #modals="{ editor, config }">
    <YourCustomModal :editor="editor" />
  </template>
</CollabEditorApp>

🔌 Integration Examples

The SDK includes fully-functional modals for common features. Just provide the data and handle the events:

<template>
  <CollabEditorApp
    v-model="content"
    :config="editorConfig"
    :onlineUsers="onlineUsers"
    :documents="documents"
    :currentDocumentId="currentDocId"
    :isTrashView="isTrashView"
    :documentsLoading="docsLoading"
    @ai-generate="handleAIGenerate"
    @rename-document="handleRenameDocument"
    @delete-document="handleDeleteDocument"
    @restore-document="handleRestoreDocument"
    @select-document="handleSelectDocument"
  />
</template>

<script setup>
import { ref } from 'vue'
import { CollabEditorApp } from '@jitword/collab-editor'

const currentDocId = ref('doc-123')
const documents = ref([
  { id: 'doc-1', name: 'Project Proposal', updatedAt: Date.now() },
  { id: 'doc-2', name: 'Meeting Notes', updatedAt: Date.now() - 86400000 }
])
const isTrashView = ref(false)
const docsLoading = ref(false)

const editorConfig = {
  roomName: 'my-room',
  enableDocumentList: true,
  enableShare: true,
  enableAI: true,
  // Customize modals
  shareConfig: {
    showQRCode: true,
    enableReadLink: true,  // Enable read-only link tab
    editLinkLabel: '✏️ Edit Link',
    readLinkLabel: '👁️ Read-only Link',
    editDescription: 'Share this link with others to collaborate in real-time:',
    readDescription: 'Share this read-only link. Others can only view the document:',
    showStats: true
  },
  aiConfig: {
    placeholder: 'Describe what you want to write...',
    quickPrompts: [
      { icon: '📝', label: 'Write', value: 'Write a professional email' }
    ]
  },
  aiSettingsConfig: {
    title: '⚙️ AI Settings',
    okText: 'Save Settings',
    apiKeyPlaceholder: 'Enter your API key',
    hint: '🔒 Your API keys are stored locally in your browser',
    storageKey: 'my_app_ai_settings',
    autoSave: false
  },
  docsConfig: {
    title: 'My Documents',
    enableRename: true,
    enableDelete: true,
    enableTrash: true
  }
}

// Handle AI generation
const handleAIGenerate = async ({ prompt, editor }) => {
  const response = await fetch('/api/ai/generate', {
    method: 'POST',
    body: JSON.stringify({ prompt })
  })
  const { text } = await response.json()
  editor.commands.insertContent(text)
}

// Handle document rename
const handleRenameDocument = async (docId, newName, onSuccess) => {
  const response = await fetch(`/api/documents/${docId}`, {
    method: 'PATCH',
    body: JSON.stringify({ name: newName })
  })
  
  if (response.ok) {
    // Update local state
    const doc = documents.value.find(d => d.id === docId)
    if (doc) doc.name = newName
    // Notify success (closes edit mode)
    onSuccess()
  }
}

// Handle document delete
const handleDeleteDocument = async (docId) => {
  await fetch(`/api/documents/${docId}`, { method: 'DELETE' })
  // Reload documents
  loadDocuments()
}

// Handle document restore
const handleRestoreDocument = async (docId) => {
  await fetch(`/api/documents/${docId}/restore`, { method: 'POST' })
  loadDocuments()
}

// Handle document select
const handleSelectDocument = (docId) => {
  currentDocId.value = docId
  router.push(`/editor/${docId}`)
}
</script>

Custom Modals (Advanced)

If you need complete control, use custom modals:

<CollabEditorApp
  v-model="content"
  :config="{ useBuiltinModals: false }"
  @ai-click="customAIModal = true"
  @share-click="customShareModal = true"
>
  <template #modals="{ editor, config }">
    <MyCustomAIModal v-model:visible="customAIModal" :editor="editor" />
    <MyCustomShareModal v-model:visible="customShareModal" />
  </template>
</CollabEditorApp>

Read Mode Integration

The SDK handles read mode automatically:

Default behavior (opens /read/{docId}):

<CollabEditorApp
  :currentDocumentId="currentDocId"
  :config="{ enableReadMode: true }"
/>

Using built-in read mode UI (simple header, no toolbar):

<CollabEditorApp
  v-model="content"
  :config="{
    readMode: true,
    documentTitle: 'My Document',
    readModeBadgeText: 'Read-only Mode',
    editable: false  // Disable editing
  }"
/>

What happens in read mode:

  • ❌ Toolbar is hidden
  • ❌ Header buttons are hidden
  • ❌ Table of contents sidebar is hidden
  • ❌ Footer is hidden
  • ✅ Simple header with document title and "Read-only" badge
  • ✅ Document statistics (paragraphs & characters)
  • ✅ Clean, distraction-free reading experience

Custom URL pattern:

const editorConfig = {
  enableReadMode: true,
  getReadModeUrl: (docId) => `/documents/${docId}/preview`
}

Custom handler (e.g., open modal instead):

const editorConfig = {
  enableReadMode: true,
  onReadModeClick: ({ editor, currentDocumentId }) => {
    showReadModeModal.value = true
  }
}

Real-time Collaboration with Yjs

All collaboration dependencies are bundled! No need to install yjs, y-websocket, or Tiptap extensions separately.

import { 
  CollabEditorApp,
  Y,                  // Yjs CRDT
  WebsocketProvider,  // WebSocket provider
  Collaboration,      // Tiptap extension
  CollaborationCursor // Collaborative cursors
} from '@jitword/collab-editor'

const ydoc = new Y.Doc()
const provider = new WebsocketProvider(
  'wss://your-websocket-server.com',
  'document-id',
  ydoc
)

// Update online users from provider awareness
provider.awareness.on('change', () => {
  const states = Array.from(provider.awareness.getStates().entries())
  onlineUsers.value = states.map(([clientID, state]) => ({
    id: clientID,
    name: state.user?.name || `User ${clientID}`,
    color: state.user?.color || '3b82f6'
  }))
})

const editorConfig = {
  // ... other config
  extensions: [
    NotionKit,
    Collaboration.configure({ document: ydoc }),
    CollaborationCursor.configure({ provider })
  ]
}

Custom File Upload

const editorConfig = {
  // ... other config
  uploadFn: async (file) => {
    const formData = new FormData()
    formData.append('file', file)
    
    const response = await fetch('https://your-api.com/upload', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${yourToken}`
      },
      body: formData
    })
    
    const data = await response.json()
    return data.url // Return the uploaded file URL
  }
}

AI Integration

const handleAIClick = async ({ editor }) => {
  // Get selected text
  const { from, to } = editor.state.selection
  const selectedText = editor.state.doc.textBetween(from, to, ' ')
  
  // Call your AI service
  const response = await fetch('https://your-ai-api.com/complete', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${yourAIKey}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      prompt: selectedText,
      context: 'improve_writing'
    })
  })
  
  const result = await response.json()
  
  // Insert AI response
  editor.chain().focus().insertContent(result.text).run()
}

AI Settings Modal

The built-in AI Settings modal allows users to configure their AI provider, model, and API key:

const editorConfig = {
  enableAISettings: true,  // Show AI Settings button
  aiSettingsConfig: {
    title: '⚙️ AI Settings',
    okText: 'Save Settings',
    cancelText: 'Cancel',
    apiKeyPlaceholder: 'Enter your API key (saved locally)',
    hint: '🔒 Your API keys are stored locally in your browser and never sent to our servers',
    storageKey: 'my_app_ai_settings',  // localStorage key for settings
    autoSave: false  // false = manual save, true = auto-save on change
  }
}

Features:

  • Provider selection (DeepSeek, Kimi, OpenAI, Custom)
  • Model selection (auto-updates based on provider)
  • API key management (stored in localStorage)
  • Custom base URL for OpenAI-compatible endpoints
  • Temperature control (0-2)
  • Secure local storage (never sent to servers)

Usage:

  1. User clicks "AI Settings" button in header
  2. Modal opens with current settings
  3. User configures provider, model, and API key
  4. Settings are saved to localStorage
  5. AI Writer modal uses these settings for generation

Version History Modal

The built-in Version History modal provides a complete version control system with create, restore, preview, edit, and delete operations:

<template>
  <CollabEditorApp
    v-model="content"
    :config="editorConfig"
    :currentDocumentId="currentDocId"
    @version-restore="handleVersionRestore"
    @version-create="handleVersionCreate"
    @version-update="handleVersionUpdate"
    @version-delete="handleVersionDelete"
    @version-preview="handleVersionPreview"
  />
</template>

<script setup>
import { ref } from 'vue'
import { CollabEditorApp, Message } from '@jitword/collab-editor'

const currentDocId = ref('doc-123')
const content = ref({ type: 'doc', content: [] })

const editorConfig = {
  enableVersions: true,  // Show Versions button
  versionConfig: {
    title: 'Version History',
    saveButtonText: 'Save Version',
    emptyText: 'No version history yet',
    autoSaveLabel: 'Auto',
    restoreText: 'Restore',
    editText: 'Edit Info',
    deleteText: 'Delete',
    previewText: 'Preview',
    loadMoreText: 'Load More',
    
    // Required: Load versions from your backend
    onLoadVersions: async (documentId, page, pageSize) => {
      const response = await fetch(
        `/api/documents/${documentId}/versions?page=${page}&pageSize=${pageSize}`
      )
      const data = await response.json()
      
      return {
        versions: data.versions.map(v => ({
          id: v.id,
          title: v.title,
          description: v.description,
          createdAt: v.createdAt,  // ISO string
          author: v.author,
          size: v.size,  // bytes
          isAutoSave: v.isAutoSave  // boolean
        })),
        total: data.total
      }
    },
    
    // Required: Create new version
    onCreateVersion: async (versionData) => {
      await fetch(`/api/documents/${versionData.documentId}/versions`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          content: versionData.content,
          title: versionData.title,
          description: versionData.description,
          isAutoSave: versionData.isAutoSave
        })
      })
    },
    
    // Required: Get version content for preview/restore
    onGetVersion: async (documentId, versionId) => {
      const response = await fetch(
        `/api/documents/${documentId}/versions/${versionId}`
      )
      const data = await response.json()
      return data.content  // ProseMirror JSON or HTML
    },
    
    // Required: Restore version
    onRestoreVersion: async (content) => {
      // Update editor with restored content
      // This is typically handled in the event handler below
    },
    
    // Optional: Update version metadata
    onUpdateVersion: async (updateData) => {
      await fetch(
        `/api/documents/${updateData.documentId}/versions/${updateData.versionId}`,
        {
          method: 'PATCH',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            title: updateData.title,
            description: updateData.description
          })
        }
      )
    },
    
    // Optional: Delete version
    onDeleteVersion: async (documentId, versionId) => {
      await fetch(
        `/api/documents/${documentId}/versions/${versionId}`,
        { method: 'DELETE' }
      )
    }
  }
}

// Handle version restore - update editor content
const handleVersionRestore = (content) => {
  // Update the editor with restored version
  content.value = content
  Message.success('Version restored successfully!')
}

// Handle version create - track in analytics
const handleVersionCreate = (versionData) => {
  console.log('Version created:', versionData)
  // Optional: Send analytics, update UI, etc.
}

// Handle version update - track metadata changes
const handleVersionUpdate = (updateData) => {
  console.log('Version updated:', updateData)
}

// Handle version delete - cleanup
const handleVersionDelete = (deleteData) => {
  console.log('Version deleted:', deleteData)
}

// Handle version preview - track which versions users view
const handleVersionPreview = (previewData) => {
  console.log('Version previewed:', previewData)
}
</script>

Features:

  • ✅ Create new versions with title and description
  • ✅ Preview versions in modal
  • ✅ Restore to any previous version
  • ✅ Edit version metadata (title, description)
  • ✅ Delete versions with confirmation
  • ✅ Auto-save label for automatic backups
  • ✅ Pagination with "Load More"
  • ✅ Version statistics (creation time, author, size)

Version Events:

Event Payload Description
@version-restore content (Object) Emitted when user restores a version. Update your editor content.
@version-create { documentId, content, title, description, isAutoSave, author } Emitted after version is created. Use for analytics.
@version-update { documentId, versionId, title, description } Emitted when version metadata is updated.
@version-delete { documentId, versionId, version } Emitted when version is deleted. Handle cleanup.
@version-preview { documentId, versionId, version, content } Emitted when user previews a version. Track analytics.

How it works:

  1. User clicks "Versions" button in header → Opens drawer
  2. SDK calls onLoadVersions() to fetch version list
  3. User clicks "Save Version" → SDK calls onCreateVersion() → Emits @version-create
  4. User clicks "Preview" → SDK calls onGetVersion() → Shows modal → Emits @version-preview
  5. User clicks "Restore" → SDK calls onGetVersion() → Emits @version-restore → You update editor
  6. User clicks "Edit Info" → Updates metadata → SDK calls onUpdateVersion() → Emits @version-update
  7. User clicks "Delete" → Shows confirmation → SDK calls onDeleteVersion() → Emits @version-delete

Best Practices:

  • Store versions in your database with documentId as foreign key
  • Include metadata: title, description, author, createdAt, size
  • Mark auto-saves with isAutoSave: true for visual distinction
  • Implement pagination for performance (default 10 versions per page)
  • Use events for analytics and UI updates
  • Handle restore by updating your v-model content

Keyboard Shortcuts

The editor supports keyboard shortcuts out of the box:

Save Document (Command+S / Ctrl+S)

The save shortcut prevents the browser's default save dialog and emits a save event:

Option 1: Handle via event listener (recommended):

<template>
  <CollabEditorApp
    v-model="content"
    :config="editorConfig"
    :currentDocumentId="currentDocId"
    @save="handleSave"
  />
</template>

<script setup>
const handleSave = async ({ editor, content, currentDocumentId }) => {
  // Save to your backend
  await fetch(`/api/documents/${currentDocumentId}`, {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ content })
  })
  
  // Show success message
  Message.success('Document saved!')
}
</script>

Option 2: Provide custom handler in config:

const editorConfig = {
  // ... other config
  onSave: async ({ editor, content, currentDocumentId }) => {
    // Your custom save logic
    await saveToDatabase(currentDocumentId, content)
    showNotification('Saved!')
  }
}

What happens:

  • User presses Command+S (Mac) or Ctrl+S (Windows/Linux)
  • Browser's default save dialog is prevented
  • Your save handler is called with editor instance, content, and document ID
  • You can save to backend, localStorage, or any storage

🎨 Customization

Custom Theme

The SDK uses CSS variables for theming. You can override them:

:root {
  --color-border-1: #e5e7eb;
  --color-text-2: #6b7280;
  --color-text-3: #9ca3af;
}

Custom Toolbar Category

const editorConfig = {
  defaultCategory: 'insert', // 'home' | 'insert' | 'view' | 'export'
  // ... other config
}

📱 Responsive Design

The SDK automatically adapts to different screen sizes:

const isMobile = computed(() => window.innerWidth < 768)
const isTablet = computed(() => window.innerWidth >= 768 && window.innerWidth < 1024)

const editorConfig = {
  isMobile: isMobile.value,
  isTablet: isTablet.value,
  // ... other config
}

🛠️ Development

# Install dependencies
pnpm install

# Build SDK
pnpm run build

# Watch mode (for development)
pnpm run dev

# Run example
pnpm run dev:example

📄 License

MIT Š JitWord

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

💡 Next Steps

After publishing v1.0.0, we'll focus on:

  • 🔐 Security: Keep API keys and authentication in user code
  • 🔌 Flexibility: Support any collaboration backend (Yjs, Socket.io, custom)
  • 📦 Lightweight: Remove specific network libraries from SDK
  • 🎯 Clear Responsibilities: SDK handles UI, users handle data pnpm install

Build SDK

pnpm run build

Watch mode (for development)

pnpm run dev

Run example

pnpm run dev:example


## 📄 License

MIT Š JitWord

## 🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## 🔗 Links

- [GitHub Repository](https://github.com/jitword/collab-editor)
- [Documentation](https://docs.jitword.com)
- [Issue Tracker](https://github.com/jitword/collab-editor/issues)

## 💡 Next Steps

After publishing v1.0.0, we'll focus on:

- 🔐 **Security**: Keep API keys and authentication in user code
- 🔌 **Flexibility**: Support any collaboration backend (Yjs, Socket.io, custom)
- 📦 **Lightweight**: Remove specific network libraries from SDK
- 🎯 **Clear Responsibilities**: SDK handles UI, users handle data