"use client"; import { HocuspocusProviderWebsocketComponent, HocuspocusRoom, } from "@hocuspocus/provider-react"; import React, { useCallback } from "react"; import CollaborationStatus from "./CollaborationStatus"; import CollaborativeEditor from "./CollaborativeEditor"; import ConnectedUsers from "./ConnectedUsers"; export default function ArticleEditor({ slug }: { slug: string }) { const handleAuthFailed = useCallback( (data: { reason: string }) => { console.error(`[Editor 1] Auth failed for "${slug}":`, data.reason); }, [slug], ); return (
{/* Header */}

Article #{slug} provider-react

Using @hocuspocus/provider-react hooks and components

{/* Main content */}
{/* Two independent WebSocket connections, each with its own room */}
{/* Editor 1 — event handlers via HocuspocusRoom props */} console.log("[Editor 1] Connection closed:", data.event) } onSynced={(data) => console.log("[Editor 1] Synced:", data.state) } >

Editor 1

Event handlers via props
{/* Editor 2 — event handlers via useHocuspocusEvent hook (see CollaborationStatus) */}

Editor 2

Event handlers via hook
{/* Info panel */}

@hocuspocus/provider-react Demo

This demo uses the new React-specific package. Each editor is wrapped in its own{" "} HocuspocusProviderWebsocketComponent {" "} (independent WebSocket) and{" "} HocuspocusRoom . Status is read via{" "} useHocuspocusConnectionStatus() ,{" "} useHocuspocusSyncStatus() , and{" "} useHocuspocusAwareness() {" "} hooks — no manual event listeners needed.

); }