When the realtime socket drops and the UI keeps rendering as if everything is fine, users type messages into a dead channel, assume their posts sent, and discover hours later that nothing reached the server. That silent failure mode destroys trust in the product, generates duplicate support tickets, and corrupts conversation ordering once reconnection flushes a backlog of stale sends. A visible connection indicator is the primary user-experience affordance that distinguishes a working realtime feature from one the user has to guess at, and its absence is the top cause of reported bugs in chat and collaboration tools.
Low because the defect is a UX gap with no security impact, though it directly drives support load and silent message loss.
Track the socket's lifecycle in React state and render a distinct visual for each of connected, connecting, and disconnected. Subscribe to connect, disconnect, and connect_error in a single effect inside a component like src/components/ConnectionIndicator.tsx, and return the subscription cleanup so stale handlers do not leak across remounts.
const [state, setState] = useState<'connected' | 'connecting' | 'disconnected'>('connecting');
useEffect(() => {
socket.on('connect', () => setState('connected'));
socket.on('disconnect', () => setState('disconnected'));
socket.on('connect_error', () => setState('disconnected'));
return () => { socket.off('connect'); socket.off('disconnect'); socket.off('connect_error'); };
}, []);
ID: community-realtime.realtime-ux.connection-state-ui
Severity: low
What to look for: Count all connection state display elements in the UI. Enumerate the states handled: connected, connecting, reconnecting, disconnected. For each state, classify whether a distinct visual indicator is rendered.
Pass criteria: The UI displays a connection state indicator that updates when the connection status changes. At least 3 distinct states must be visually distinguishable (connected, connecting, disconnected). Report even on pass: "UI shows N distinct connection states."
Fail criteria: No connection state is displayed to the user, or it is displayed but does not update on disconnect/reconnect.
Skip (N/A) when: Never — users need to know if real-time features are working.
Detail on fail: "No connection indicator in the UI. Users don't know if they are offline or why messages aren't sending."
Remediation: Display connection state to users:
const [connectionState, setConnectionState] = useState<'connected' | 'connecting' | 'disconnected'>('connecting');
useEffect(() => {
socket.on('connect', () => setConnectionState('connected'));
socket.on('disconnect', () => setConnectionState('disconnected'));
socket.on('connect_error', () => setConnectionState('disconnected'));
return () => {
socket.off('connect');
socket.off('disconnect');
socket.off('connect_error');
};
}, []);
return (
<div className="connection-indicator">
{connectionState === 'connected' && <span className="status-online">●</span>}
{connectionState === 'connecting' && <span className="status-connecting">◐</span>}
{connectionState === 'disconnected' && <span className="status-offline">○</span>}
</div>
);