📈(frontend) add analytics for disconnect/reconnect events

Track connection issues to identify user problems. Skip client-initiated
disconnects (normal flow). Disconnect events provide richer data than
reconnect events which lack reason details.

Next: Add error screen for JOIN_FAILURE disconnects to trigger support
workflow for users experiencing connection problems.
This commit is contained in:
lebaudantoine
2025-06-11 17:55:10 +02:00
committed by aleb_the_flash
parent f9614fc108
commit e6caa0a2fd
2 changed files with 37 additions and 0 deletions

View File

@@ -0,0 +1,34 @@
import { useRoomContext } from '@livekit/components-react'
import { useEffect } from 'react'
import { DisconnectReason, RoomEvent } from 'livekit-client'
import { useIsAnalyticsEnabled } from '@/features/analytics/hooks/useIsAnalyticsEnabled'
import posthog from 'posthog-js'
export const useConnectionObserver = () => {
const room = useRoomContext()
const isAnalyticsEnabled = useIsAnalyticsEnabled()
useEffect(() => {
if (!isAnalyticsEnabled) return
const handleReconnect = () => {
posthog.capture('reconnect-event')
}
const handleDisconnect = (
disconnectReason: DisconnectReason | undefined
) => {
if (disconnectReason == DisconnectReason.CLIENT_INITIATED) return
posthog.capture('disconnect-event', {
reason: disconnectReason && DisconnectReason[disconnectReason],
})
}
room.on(RoomEvent.Disconnected, handleDisconnect)
room.on(RoomEvent.Reconnecting, handleReconnect)
return () => {
room.off(RoomEvent.Disconnected, handleDisconnect)
room.off(RoomEvent.Reconnecting, handleReconnect)
}
}, [room, isAnalyticsEnabled])
}

View File

@@ -30,6 +30,7 @@ import { SidePanel } from '../components/SidePanel'
import { useSidePanel } from '../hooks/useSidePanel'
import { RecordingStateToast } from '@/features/recording'
import { ScreenShareErrorModal } from '../components/ScreenShareErrorModal'
import { useConnectionObserver } from '../hooks/useConnectionObserver'
const LayoutWrapper = styled(
'div',
@@ -74,6 +75,8 @@ export function VideoConference({ ...props }: VideoConferenceProps) {
const lastAutoFocusedScreenShareTrack =
React.useRef<TrackReferenceOrPlaceholder | null>(null)
useConnectionObserver()
const tracks = useTracks(
[
{ source: Track.Source.Camera, withPlaceholder: true },