Programmatic access to support widget state, navigation, visitor management, and more.

Overview

Cossistant provides React hooks for programmatic control over every aspect of the support widget. These hooks follow a layered architecture:

  • Core hooks (useSupport, useVisitor) - Primary integration points
  • Widget state hooks (useSupportConfig, useSupportNavigation) - Control widget behavior
  • Page hooks (useHomePage, useConversationPage) - Build custom pages
  • Utility hooks (useFileUpload, useMessageComposer) - Compose functionality

useSupport

Access support widget state and controls from any client component.

Basic Example

tscomponents/custom-support-button.tsx
"use client";
 
import { useSupport } from "@cossistant/next";
 
export function CustomSupportButton() {
  const { isOpen, toggle, unreadCount } = useSupport();
 
  return (
    <button
      onClick={toggle}
      className="relative rounded-lg bg-primary px-4 py-2 text-white"
    >
      Support
      {unreadCount > 0 && (
        <span className="absolute -right-1 -top-1 flex h-5 w-5 items-center justify-center rounded-full bg-red-500 text-xs">
          {unreadCount}
        </span>
      )}
    </button>
  );
}

Return Values

Name

Type

useVisitor

Programmatically identify visitors and manage contact metadata.

Example: Identify on Auth

tscomponents/auth-handler.tsx
"use client";
 
import { useVisitor } from "@cossistant/next";
import { useEffect } from "react";
 
export function AuthHandler({ user }) {
  const { visitor, identify } = useVisitor();
 
  useEffect(() => {
    // Only identify if we have a user and visitor isn't already a contact
    if (user && !visitor?.contact) {
      identify({
        externalId: user.id,
        email: user.email,
        name: user.name,
        image: user.avatar,
      });
    }
  }, [user, visitor?.contact, identify]);
 
  return null;
}

Example: Update Metadata on Action

tscomponents/upgrade-button.tsx
"use client";
 
import { useVisitor } from "@cossistant/next";
 
export function UpgradeButton() {
  const { setVisitorMetadata } = useVisitor();
 
  const handleUpgrade = async () => {
    // Upgrade user's plan
    await upgradeToPro();
 
    // Update contact metadata so support agents see the change
    await setVisitorMetadata({
      plan: "pro",
      upgradedAt: new Date().toISOString(),
      mrr: 99,
    });
  };
 
  return <button onClick={handleUpgrade}>Upgrade to Pro</button>;
}

Return Values

Name

Type

identify() Parameters

Parameter

Type

useSupportConfig

Access and control widget visibility and size configuration.

Basic Example

tscomponents/custom-toggle.tsx
"use client";
 
import { useSupportConfig } from "@cossistant/react/support";
 
export function CustomToggle() {
  const { isOpen, open, close, toggle, size } = useSupportConfig();
 
  return (
    <div className="flex gap-2">
      <button onClick={toggle}>
        {isOpen ? "Close Support" : "Open Support"}
      </button>
      <span>Size: {size}</span>
    </div>
  );
}

Return Values

Name

Type

useSupportNavigation

Access navigation state and routing methods for the widget.

Basic Example

tscomponents/navigation-buttons.tsx
"use client";
 
import { useSupportNavigation } from "@cossistant/react/support";
 
export function NavigationButtons() {
  const { page, navigate, goBack, canGoBack } = useSupportNavigation();
 
  return (
    <div className="flex gap-2">
      {canGoBack && <button onClick={goBack}>← Back</button>}
      <span>Current page: {page}</span>
      <button onClick={() => navigate({ page: "HOME" })}>Go Home</button>
      <button
        onClick={() =>
          navigate({
            page: "CONVERSATION",
            params: { conversationId: "conv_123" }
          })
        }
      >
        Open Conversation
      </button>
    </div>
  );
}

Return Values

Name

Type

useSupportHandle

Access the imperative handle from within the widget tree. Alternative to using refs on the Support component.

Basic Example

tscomponents/help-button.tsx
"use client";
 
import { useSupportHandle } from "@cossistant/react/support";
 
export function HelpButton() {
  const support = useSupportHandle();
 
  const handleNeedHelp = () => {
    // Open support and start a new conversation
    support?.startConversation("I need help with my order");
  };
 
  return (
    <button onClick={handleNeedHelp}>
      Need Help?
    </button>
  );
}

Return Values

Name

Type

useHomePage

Logic hook for building custom home pages. Provides all state and actions needed for the home page.

Basic Example

tspages/custom-home.tsx
"use client";
 
import { useHomePage } from "@cossistant/react";
 
export function CustomHomePage() {
  const home = useHomePage({
    onStartConversation: () => console.log("Conversation started"),
    onOpenConversation: (id) => console.log("Opened:", id),
  });
 
  return (
    <div>
      <h1>Welcome!</h1>
 
      {home.lastOpenConversation && (
        <button onClick={() => home.openConversation(home.lastOpenConversation!.id)}>
          Continue conversation
        </button>
      )}
 
      <button onClick={() => home.startConversation()}>
        Start new conversation
      </button>
 
      {home.availableConversationsCount > 0 && (
        <button onClick={home.openConversationHistory}>
          View {home.availableConversationsCount} conversations
        </button>
      )}
    </div>
  );
}

Return Values

Name

Type

useConversationPage

Logic hook for building custom conversation pages. Manages the conversation lifecycle, messages, and composer.

Basic Example

tspages/custom-conversation.tsx
"use client";
 
import { useConversationPage } from "@cossistant/react";
 
export function CustomConversationPage({ conversationId }: { conversationId: string }) {
  const conversation = useConversationPage({
    conversationId,
    onConversationCreated: (id) => console.log("Created:", id),
  });
 
  return (
    <div>
      {/* Messages */}
      <div className="flex-1 overflow-y-auto">
        {conversation.items.map((item) => (
          <div key={item.id}>{/* Render message */}</div>
        ))}
      </div>
 
      {/* Composer */}
      {conversation.isConversationOpen && (
        <form onSubmit={(e) => { e.preventDefault(); conversation.composer.submit(); }}>
          <input
            value={conversation.composer.message}
            onChange={(e) => conversation.composer.setMessage(e.target.value)}
            placeholder="Type a message..."
          />
          <button type="submit" disabled={!conversation.composer.canSubmit}>
            Send
          </button>
        </form>
      )}
    </div>
  );
}

Return Values

Name

Type

useMessageComposer

Hook for managing message composition with file attachments.

Basic Example

tscomponents/message-input.tsx
"use client";
 
import { useMessageComposer } from "@cossistant/react";
 
export function MessageInput({ conversationId }: { conversationId: string }) {
  const composer = useMessageComposer({
    conversationId,
    onMessageSent: () => console.log("Message sent!"),
  });
 
  return (
    <form onSubmit={(e) => { e.preventDefault(); composer.submit(); }}>
      <input
        value={composer.message}
        onChange={(e) => composer.setMessage(e.target.value)}
        placeholder="Type a message..."
      />
      <input
        type="file"
        multiple
        onChange={(e) => {
          if (e.target.files) {
            composer.addFiles(Array.from(e.target.files));
          }
        }}
      />
      {composer.attachments.map((file) => (
        <span key={file.name}>
          {file.name} <button onClick={() => composer.removeFile(file.name)}>×</button>
        </span>
      ))}
      <button type="submit" disabled={!composer.canSubmit || composer.isSubmitting}>
        {composer.isSubmitting ? "Sending..." : "Send"}
      </button>
    </form>
  );
}

Return Values

Name

Type

useFileUpload

Hook for handling file uploads with progress tracking.

Basic Example

tscomponents/file-uploader.tsx
"use client";
 
import { useFileUpload } from "@cossistant/react";
 
export function FileUploader() {
  const upload = useFileUpload({
    onUploadComplete: (result) => console.log("Uploaded:", result),
    onError: (error) => console.error("Upload failed:", error),
  });
 
  return (
    <div>
      <input
        type="file"
        onChange={(e) => {
          if (e.target.files?.[0]) {
            upload.uploadFile(e.target.files[0]);
          }
        }}
      />
      {upload.isUploading && (
        <div>
          <progress value={upload.progress} max={100} />
          <span>{upload.progress}%</span>
        </div>
      )}
      {upload.error && <p className="text-red-500">{upload.error.message}</p>}
    </div>
  );
}

Return Values

Name

Type

useSupportText

Access the localization system for the support widget.

Basic Example

tscomponents/localized-button.tsx
"use client";
 
import { useSupportText } from "@cossistant/react/support";
 
export function LocalizedButton() {
  const text = useSupportText();
 
  return (
    <button>
      {text.get("common.actions.askQuestion")}
    </button>
  );
}

Return Values

Name

Type

useSupportEvents

Access the events context for subscribing to widget lifecycle events.

Basic Example

tscomponents/analytics-tracker.tsx
"use client";
 
import { useSupportEvents } from "@cossistant/react/support";
import { useEffect } from "react";
 
export function AnalyticsTracker() {
  const events = useSupportEvents();
 
  useEffect(() => {
    if (!events) return;
 
    const unsubscribe = events.subscribe("messageSent", (event) => {
      // Track in your analytics
      analytics.track("support_message_sent", {
        conversationId: event.conversationId,
      });
    });
 
    return unsubscribe;
  }, [events]);
 
  return null;
}

Return Values

Name

Type

useSupportEventEmitter

Convenience hook for emitting events from within the widget.

Return Values

Name

Type

Types

PublicVisitor

The visitor object returned by the widget, representing an anonymous or identified visitor.

Property

Type

PublicContact

Contact information for an identified visitor.

Property

Type

PublicWebsiteResponse

Website configuration and agent availability information.

Property

Type

HumanAgent

Information about a human support agent.

Property

Type

AIAgent

Information about an AI support agent.

Property

Type

CossistantClient

The underlying client instance for direct API access. Used for advanced programmatic control.

Property

Type

IdentifyParams

Parameters for the identify() function.

Property

Type

VisitorMetadata

Key-value pairs for storing custom data about contacts.

Property

Type

Type Definition: Record<string, string | number | boolean | null>

SenderType

Enum defining who can send messages.

Property

Type

Type Definition: "visitor" | "team_member" | "ai"

MessageComposer

State and actions returned by useConversationPage for message composition.

Property

Type

SupportHandle

Imperative handle for programmatic widget control via refs.

Property

Type

SupportEvent

Union type of all possible widget events.

Property

Type