Get the Live State Sync element via hook or client API.
Enable Single Editor Mode. Optionally pass config:
customMode: When true, SDK won’t automatically make HTML elements read-only for viewers. You must manage UI state manually or using the APIs listed here. Default: false
singleTabEditor: Restrict editing to a single browser tab for the editor. Default: true
Optionally enable/disable the default UI panel. Default: enabled
Optionally scope the feature to specific containers.
We recommend using the default UI for simplicity and velocity. You can customize it to change the look, feel and position of the UI. You can customize the UI by following this guide.
If you do want to create your UI from scratch then you can use the following APIs to create a similar UX: Editor and Viewer.
React / Next.js
Other Frameworks
Copy
Ask AI
const liveStateSyncElement = useLiveStateSyncUtils(); useEffect(() => { if (liveStateSyncElement) { // Enable Single Editor Mode liveStateSyncElement.enableSingleEditorMode({ customMode: false, singleTabEditor: true }); // Optional: Show default UI panel liveStateSyncElement.enableDefaultSingleEditorUI(); // Optional: Restrict to specific containers liveStateSyncElement.singleEditorModeContainerIds(['editor', 'rightPanel']); } // Cleanup on unmount return () => liveStateSyncElement.disableSingleEditorMode(); }, [liveStateSyncElement]); return ( <div id="editor"> {/* Single Editor Mode Panel UI */} <VeltSingleEditorModePanel shadowDom={false} /> </div> );
Declare the editor for the current document/session so editing is enabled for one user while others remain read-only.
You can set the current user as the editor programmatically on an explicit action.
React / Next.js
Other Frameworks
Copy
Ask AI
const liveStateSyncElement = useLiveStateSyncUtils();// Programmatically set the current user as the editor when they perform an explicit action. eg: start typing or interact with the UI.function setEditor() { liveStateSyncElement?.setUserAsEditor();}
When the editor is set, editing tools should become enabled for that user while other users are placed in read-only mode.
You can fine tune which elements are enabled/disabled by following this guide.
Step 4: Update UI to reflect editor and viewer states
Non-editor users are automatically viewers. Reflect that state in your UI.
If you are using the default UI, it will automatically reflect the editor and viewer states in the UI. You can customize it to change the look, feel and position of the UI.
React / Next.js
Other Frameworks
Copy
Ask AI
// Reflect viewer vs editor state in UIconst { isEditor, isEditorOnCurrentTab } = useUserEditorState();return ( <div> <div>Role: {isEditor ? 'Editor' : 'Viewer'}</div> {isEditor && <div>Editing on this tab: {isEditorOnCurrentTab ? 'Yes' : 'No'}</div>} </div>);
Step 6: Prevent concurrent editing by the same user (tab locking)
If the same user opens another tab and tries to edit, lock the editor to a single tab and guide them back to the active tab when needed.
React / Next.js
Other Frameworks
Copy
Ask AI
const liveStateSyncElement = useLiveStateSyncUtils();const { isEditor, isEditorOnCurrentTab } = useUserEditorState();// If the user is the editor but on the wrong tab, prompt and switchif (isEditor && isEditorOnCurrentTab === false) { // Show UX prompt like: "You are already editing this page in another tab. Continue editing there." // Provide an action to move editing to this tab: const takeOver = () => liveStateSyncElement.editCurrentTab(); // Example: <button onClick={takeOver}>Edit on this tab</button>}
Recommended UX copy: “You are already editing this page in another tab. Continue editing there.”
Initialize Velt first: Ensure the Velt client is initialized and the user/document are set before enabling Single Editor Mode.
Default UI: The built-in UI can be shown with enableDefaultSingleEditorUI() and/or by rendering <VeltSingleEditorModePanel /> (React) or <velt-single-editor-mode-panel> (HTML).
Restrict scope: Use singleEditorModeContainerIds([...]) to limit Single Editor Mode to specific containers instead of the entire DOM.
Native elements only: When customMode: true, you must mark native HTML elements with attributes to control them:
data-velt-sync-access="true" to enable control
data-velt-sync-access-disabled="true" to exclude elements
These attributes work on native elements only, not directly on React components.
Open the same document as two different users in separate browser profiles (or two windows with different auth states).
Try editing simultaneously. Only one user should be able to edit; the other stays read-only.
Use the default UI panel to request/transfer access and verify the flow.
Common issues:
UI not visible: Ensure enableDefaultSingleEditorUI() is called or the panel component/element is rendered.
Elements not disabled: If using customMode: true, ensure you set data-velt-sync-access attributes on native elements. Attributes do not attach to React components.
Editor can edit in multiple tabs: Confirm singleTabEditor is true. Use editCurrentTab() to move the editor role to the current tab.