Quick Start
Quick Start
This guide walks you through setting up real-time presence and cursors in a React application.
1. Wrap Your App
First, wrap your application with the RealtimeProvider:
// app/providers.tsx
'use client';
import { RealtimeProvider } from '@realtime-sdk/react';
export function Providers({ children }: { children: React.ReactNode }) {
return (
<RealtimeProvider
endpoint={process.env.NEXT_PUBLIC_REALTIME_URL!}
authToken={async () => {
// Fetch your auth token from your API
const res = await fetch('/api/realtime-token');
const { token } = await res.json();
return token;
}}
>
{children}
</RealtimeProvider>
);
}
2. Join a Room
Use the useRoom hook to join a collaboration room:
// components/collaborative-editor.tsx
'use client';
import { useRoom } from '@realtime-sdk/react';
import { useEffect } from 'react';
export function CollaborativeEditor({ documentId }: { documentId: string }) {
const room = useRoom(documentId);
useEffect(() => {
room.join({ metadata: { name: 'Anonymous' } });
return () => room.leave();
}, [room]);
return (
<div>
{room.status === 'joined' ? (
<Editor room={room} />
) : (
<div>Connecting...</div>
)}
</div>
);
}
3. Add Presence
Show who's online with the usePresence hook:
import { usePresence } from '@realtime-sdk/react';
function PresenceList({ room }: { room: Room }) {
const { others, self } = usePresence(room);
return (
<div className="flex gap-2">
{/* Current user */}
{self && (
<div
className="w-8 h-8 rounded-full flex items-center justify-center text-white text-sm"
style={{ backgroundColor: self.color }}
>
{self.data.name?.[0] ?? '?'}
</div>
)}
{/* Other users */}
{others.map(user => (
<div
key={user.id}
className="w-8 h-8 rounded-full flex items-center justify-center text-white text-sm"
style={{ backgroundColor: user.color }}
>
{user.data.name?.[0] ?? '?'}
</div>
))}
</div>
);
}
4. Add Cursors
Track and display cursor positions with the useCursors hook:
import { useCursors } from '@realtime-sdk/react';
function CursorOverlay({ room }: { room: Room }) {
const { cursors, updateCursor } = useCursors(room);
return (
<div
className="absolute inset-0"
onMouseMove={(e) => {
const rect = e.currentTarget.getBoundingClientRect();
updateCursor({
x: e.clientX - rect.left,
y: e.clientY - rect.top,
});
}}
onMouseLeave={() => updateCursor(null)}
>
{cursors.map(cursor => (
<div
key={cursor.id}
className="absolute pointer-events-none"
style={{
left: cursor.position.x,
top: cursor.position.y,
transform: 'translate(-2px, -2px)',
}}
>
{/* Cursor arrow */}
<svg width="24" height="24" viewBox="0 0 24 24">
<path
fill={cursor.color}
d="M5.65 3.15L20.85 12L12 14.5L8.35 21.85L5.65 3.15Z"
/>
</svg>
{/* Name label */}
<div
className="px-2 py-1 rounded text-xs text-white whitespace-nowrap"
style={{ backgroundColor: cursor.color }}
>
{cursor.name}
</div>
</div>
))}
</div>
);
}
Next Steps
- Learn about Authentication
- Add Document Sync with Yjs
- Explore the React API Reference