Creates a reactive store synchronized with a multiplayer server for real-time collaboration.

This hook manages the complete lifecycle of a collaborative tldraw session, including WebSocket connection establishment, state synchronization, user presence, and error handling. The returned store can be passed directly to the Tldraw component to enable multiplayer features.

The store progresses through multiple states:

  • loading: Establishing connection and synchronizing initial state
  • synced-remote: Successfully connected and actively synchronizing changes
  • error: Connection failed or synchronization error occurred

For optimal performance with media assets, provide an assets store that implements external blob storage. Without this, large images and videos will be stored inline as base64, causing performance issues during serialization.

Example

// Basic multiplayer setup
function CollaborativeApp() {
  const store = useSync({
    uri: 'wss://myserver.com/sync/room-123',
    assets: myAssetStore,
    userInfo: {
      id: 'user-1',
      name: 'Alice',
      color: '#ff0000',
    },
  })

  if (store.status === 'loading') {
    return <div>Connecting to collaboration session...</div>
  }

  if (store.status === 'error') {
    return <div>Failed to connect: {store.error.message}</div>
  }

  return <Tldraw store={store.store} />
}
// Dynamic authentication with reactive user info
import { atom } from '@tldraw/state'

function AuthenticatedApp() {
  const currentUser = atom('user', {
    id: 'user-1',
    name: 'Alice',
    color: '#ff0000',
  })

  const store = useSync({
    uri: async () => {
      const token = await getAuthToken()
      return `wss://myserver.com/sync/room-123?token=${token}`
    },
    assets: authenticatedAssetStore,
    userInfo: currentUser, // Reactive signal
    getUserPresence: (store, user) => {
      return {
        userId: user.id,
        userName: user.name,
        cursor: getCurrentCursor(store),
      }
    },
  })

  return <Tldraw store={store.store} />
}

Parameters

NameDescription

opts

Configuration options for multiplayer synchronization

  • uri - WebSocket server URI (string or async function returning URI)
  • assets - Asset store for blob storage (required for production use)
  • userInfo - User information for presence system (can be reactive signal)
  • getUserPresence - Optional function to customize presence data
  • onCustomMessageReceived - Handler for custom socket messages
  • roomId - Room identifier for analytics (internal use)
  • onMount - Callback when editor mounts (internal use)
  • trackAnalyticsEvent - Analytics event tracker (internal use)

Returns

A reactive store wrapper with connection status and synchronized store

Prev
squashRecordDiffs
Next
useSyncDemo