Listen to widget lifecycle events for analytics, logging, and custom integrations.

Overview

The Support widget emits events throughout its lifecycle, allowing you to:

  • Track user interactions for analytics
  • Log events for debugging
  • Trigger custom behavior based on widget activity
  • Integrate with third-party services

Event Callback Props

The simplest way to listen to events is via callback props on the <Support> component:

tsapp/layout.tsx
"use client";
 
import { Support } from "@cossistant/next";
 
export function SupportWidget() {
  return (
    <Support
      onConversationStart={({ conversationId }) => {
        analytics.track("support_conversation_started", { conversationId });
      }}
      onConversationEnd={({ conversationId }) => {
        analytics.track("support_conversation_ended", { conversationId });
      }}
      onMessageSent={({ conversationId, message }) => {
        analytics.track("support_message_sent", {
          conversationId,
          messageId: message.id,
        });
      }}
      onMessageReceived={({ conversationId, message }) => {
        analytics.track("support_message_received", {
          conversationId,
          messageId: message.id,
        });
      }}
      onError={({ error, context }) => {
        logger.error("Support widget error", { error, context });
      }}
    />
  );
}

Available Events

onConversationStart

Fired when a new conversation is created.

Parameter

Type

onConversationEnd

Fired when a conversation is closed or resolved.

Parameter

Type

onMessageSent

Fired when the visitor sends a message.

Parameter

Type

onMessageReceived

Fired when a message is received from an agent (human or AI).

Parameter

Type

onError

Fired when an error occurs within the widget.

Parameter

Type

Programmatic Event Handling

For more control, use the useSupportEvents hook to subscribe to events from any component within the widget:

tscomponents/analytics-tracker.tsx
"use client";
 
import { useSupportEvents } from "@cossistant/next/support";
import { useEffect } from "react";
 
export function AnalyticsTracker() {
  const events = useSupportEvents();
 
  useEffect(() => {
    if (!events) return;
 
    // Subscribe to multiple event types
    const unsubscribes = [
      events.subscribe("conversationStart", (event) => {
        analytics.track("conversation_started", event);
      }),
      events.subscribe("messageSent", (event) => {
        analytics.track("message_sent", event);
      }),
      events.subscribe("messageReceived", (event) => {
        analytics.track("message_received", event);
      }),
      events.subscribe("error", (event) => {
        errorTracker.captureException(event.error, {
          extra: { context: event.context },
        });
      }),
    ];
 
    // Cleanup all subscriptions
    return () => {
      unsubscribes.forEach((unsubscribe) => unsubscribe());
    };
  }, [events]);
 
  return null;
}

Emitting Custom Events

From within custom pages or components, use useSupportEventEmitter to emit events:

tspages/custom-conversation.tsx
"use client";
 
import { useSupportEventEmitter } from "@cossistant/next/support";
 
export function CustomConversationPage({ conversationId }: { conversationId: string }) {
  const emitter = useSupportEventEmitter();
 
  const handleSendMessage = async (message: string) => {
    try {
      const sentMessage = await sendMessage(conversationId, message);
 
      // Emit the event for other listeners
      emitter.emitMessageSent(conversationId, sentMessage);
    } catch (error) {
      emitter.emitError(error as Error, "message_send_failed");
    }
  };
 
  return (
    // ...your component
  );
}

Integration Examples

Google Analytics 4

tscomponents/ga-tracker.tsx
"use client";
 
import { Support } from "@cossistant/next";
 
export function SupportWithGA() {
  return (
    <Support
      onConversationStart={({ conversationId }) => {
        gtag("event", "support_conversation_start", {
          conversation_id: conversationId,
        });
      }}
      onMessageSent={({ conversationId, message }) => {
        gtag("event", "support_message_sent", {
          conversation_id: conversationId,
          message_id: message.id,
        });
      }}
    />
  );
}

Sentry Error Tracking

tscomponents/sentry-support.tsx
"use client";
 
import { Support } from "@cossistant/next";
import * as Sentry from "@sentry/react";
 
export function SupportWithSentry() {
  return (
    <Support
      onError={({ error, context }) => {
        Sentry.captureException(error, {
          tags: {
            component: "support_widget",
          },
          extra: {
            context,
          },
        });
      }}
    />
  );
}

Segment

tscomponents/segment-support.tsx
"use client";
 
import { Support } from "@cossistant/next";
import { analytics } from "./analytics";
 
export function SupportWithSegment() {
  return (
    <Support
      onConversationStart={({ conversationId }) => {
        analytics.track("Support Conversation Started", {
          conversationId,
        });
      }}
      onConversationEnd={({ conversationId }) => {
        analytics.track("Support Conversation Ended", {
          conversationId,
        });
      }}
      onMessageSent={({ conversationId, message }) => {
        analytics.track("Support Message Sent", {
          conversationId,
          messageId: message.id,
          hasAttachments: message.attachments?.length > 0,
        });
      }}
    />
  );
}

PostHog

tscomponents/posthog-support.tsx
"use client";
 
import { Support } from "@cossistant/next";
import { usePostHog } from "posthog-js/react";
 
export function SupportWithPostHog() {
  const posthog = usePostHog();
 
  return (
    <Support
      onConversationStart={({ conversationId }) => {
        posthog.capture("support_conversation_started", {
          conversationId,
        });
      }}
      onMessageSent={({ conversationId }) => {
        posthog.capture("support_message_sent", {
          conversationId,
        });
      }}
    />
  );
}

Event Types

All event types are exported for TypeScript usage:

import type {
  SupportEvent,
  SupportEventType,
  ConversationStartEvent,
  ConversationEndEvent,
  MessageSentEvent,
  MessageReceivedEvent,
  ErrorEvent,
  SupportEventCallbacks,
} from "@cossistant/next/support";

Property

Type