Skip to main content
{
  "component": "CometChatCallButtons",
  "package": "@cometchat/chat-uikit-react",
  "import": "import { CometChatCallButtons } from \"@cometchat/chat-uikit-react\";",
  "cssImport": "import \"@cometchat/chat-uikit-react/css-variables.css\";",
  "description": "Voice and video call initiation buttons for user or group conversations.",
  "cssRootClass": ".cometchat-call-button",
  "primaryOutput": {
    "description": "Initiates calls via SDK, emits CometChatCallEvents"
  },
  "props": {
    "data": {
      "user": { "type": "CometChat.User", "default": "undefined" },
      "group": { "type": "CometChat.Group", "default": "undefined" }
    },
    "callbacks": {
      "onError": "((error: CometChat.CometChatException) => void) | null",
      "onVoiceCallClick": "(user?: CometChat.User, group?: CometChat.Group) => void",
      "onVideoCallClick": "(user?: CometChat.User, group?: CometChat.Group) => void"
    },
    "visibility": {
      "hideVoiceCallButton": { "type": "boolean", "default": false },
      "hideVideoCallButton": { "type": "boolean", "default": false }
    },
    "configuration": {
      "callSettingsBuilder": "(isAudioOnlyCall: boolean, user?: CometChat.User, group?: CometChat.Group) => CallSettingsBuilder",
      "outgoingCallConfiguration": "OutgoingCallConfiguration"
    }
  },
  "events": [
    { "name": "CometChatCallEvents.ccOutgoingCall", "payload": "CometChat.Call" },
    { "name": "CometChatCallEvents.ccCallRejected", "payload": "CometChat.Call" },
    { "name": "CometChatCallEvents.ccCallEnded", "payload": "CometChat.Call" }
  ]
}

Overview

Call buttons provide a simple way to add voice and video calling to your chat. Pass a user for 1-on-1 calls or a group for group calls. The component handles call initiation, displays the outgoing call screen, and manages the full call lifecycle. Time estimate: 10 minutes
Difficulty: Beginner

Prerequisites

Steps

Step 1: Add call buttons for a user

Fetch a user and display call buttons:
import { useState, useEffect } from "react";
import { CometChat } from "@cometchat/chat-sdk-javascript";
import { CometChatCallButtons } from "@cometchat/chat-uikit-react";
import "@cometchat/chat-uikit-react/css-variables.css";

function UserCallButtons() {
  const [user, setUser] = useState<CometChat.User>();

  useEffect(() => {
    CometChat.getUser("user_uid").then((u) => setUser(u));
  }, []);

  if (!user) return null;

  return <CometChatCallButtons user={user} />;
}
Call buttons

Step 2: Add call buttons for a group

For group calls, pass a group instead:
import { useState, useEffect } from "react";
import { CometChat } from "@cometchat/chat-sdk-javascript";
import { CometChatCallButtons } from "@cometchat/chat-uikit-react";

function GroupCallButtons() {
  const [group, setGroup] = useState<CometChat.Group>();

  useEffect(() => {
    CometChat.getGroup("group_guid").then((g) => setGroup(g));
  }, []);

  if (!group) return null;

  return <CometChatCallButtons group={group} />;
}

Step 3: Show only voice or video button

Hide one of the buttons based on your needs:
// Voice calls only
<CometChatCallButtons user={user} hideVideoCallButton={true} />

// Video calls only
<CometChatCallButtons user={user} hideVoiceCallButton={true} />

Step 4: Override call initiation behavior

Handle call clicks with custom logic:
import { CometChatCallButtons } from "@cometchat/chat-uikit-react";
import { CometChat } from "@cometchat/chat-sdk-javascript";

function CustomCallButtons({ user }: { user: CometChat.User }) {
  return (
    <CometChatCallButtons
      user={user}
      onVoiceCallClick={(user, group) => {
        console.log("Custom voice call logic for:", user?.getName());
        // Implement your own call initiation
      }}
      onVideoCallClick={(user, group) => {
        console.log("Custom video call logic for:", user?.getName());
        // Implement your own call initiation
      }}
      onError={(error) => {
        console.error("Call error:", error);
      }}
    />
  );
}

Step 5: Customize the outgoing call screen

Configure how the outgoing call overlay appears:
import { CometChatCallButtons, OutgoingCallConfiguration } from "@cometchat/chat-uikit-react";

function StyledCallButtons({ user }: { user: CometChat.User }) {
  return (
    <CometChatCallButtons
      user={user}
      outgoingCallConfiguration={
        new OutgoingCallConfiguration({
          disableSoundForCalls: false,
          customSoundForCalls: "/sounds/ring.mp3",
          titleView: (call) => (
            <div style={{ fontSize: 24, fontWeight: "bold" }}>
              Calling {call.getCallReceiver().getName()}...
            </div>
          ),
        })
      }
    />
  );
}

Step 6: Configure call settings

Customize the call session parameters:
import { CometChatCallButtons, CometChatUIKitCalls } from "@cometchat/chat-uikit-react";

function ConfiguredCallButtons({ user }: { user: CometChat.User }) {
  return (
    <CometChatCallButtons
      user={user}
      callSettingsBuilder={(isAudioOnlyCall, user, group) =>
        new CometChatUIKitCalls.CallSettingsBuilder()
          .enableDefaultLayout(true)
          .setIsAudioOnlyCall(isAudioOnlyCall)
          .showEndCallButton(true)
          .showSwitchCameraButton(!isAudioOnlyCall)
      }
    />
  );
}

Complete Example

import { useState, useEffect } from "react";
import { CometChat } from "@cometchat/chat-sdk-javascript";
import {
  CometChatCallButtons,
  CometChatCallEvents,
  OutgoingCallConfiguration,
} from "@cometchat/chat-uikit-react";
import "@cometchat/chat-uikit-react/css-variables.css";

function ChatHeader({ userId }: { userId: string }) {
  const [user, setUser] = useState<CometChat.User>();

  useEffect(() => {
    CometChat.getUser(userId).then((u) => setUser(u));
  }, [userId]);

  // Listen for call events
  useEffect(() => {
    const outgoingSub = CometChatCallEvents.ccOutgoingCall.subscribe((call) => {
      console.log("Call initiated:", call.getSessionId());
    });

    const acceptedSub = CometChatCallEvents.ccCallAccepted.subscribe((call) => {
      console.log("Call accepted, starting session...");
    });

    const endedSub = CometChatCallEvents.ccCallEnded.subscribe((call) => {
      console.log("Call ended");
    });

    return () => {
      outgoingSub?.unsubscribe();
      acceptedSub?.unsubscribe();
      endedSub?.unsubscribe();
    };
  }, []);

  if (!user) return null;

  return (
    <div style={{ display: "flex", alignItems: "center", gap: 16, padding: 16 }}>
      <img
        src={user.getAvatar()}
        alt={user.getName()}
        style={{ width: 40, height: 40, borderRadius: "50%" }}
      />
      <div style={{ flex: 1 }}>
        <div style={{ fontWeight: "bold" }}>{user.getName()}</div>
        <div style={{ fontSize: 12, color: "#666" }}>Online</div>
      </div>
      
      <CometChatCallButtons
        user={user}
        outgoingCallConfiguration={
          new OutgoingCallConfiguration({
            customSoundForCalls: "/sounds/outgoing.mp3",
          })
        }
        onError={(error) => console.error("Call error:", error)}
      />
    </div>
  );
}

export default ChatHeader;
The call buttons are commonly used in the message header’s auxiliary view:
import {
  CometChatMessageHeader,
  CometChatCallButtons,
} from "@cometchat/chat-uikit-react";

function ChatWithCalling({ user }: { user: CometChat.User }) {
  return (
    <CometChatMessageHeader
      user={user}
      auxiliaryButtonView={<CometChatCallButtons user={user} />}
    />
  );
}

Common Issues

Pass either user or group to the component, not both. The component determines call type based on which prop is provided.
IssueSolution
Buttons disabledCheck if another call is in progress
Call not initiatingVerify CometChat Calls SDK is initialized
Outgoing screen not showingEnsure no custom onVoiceCallClick/onVideoCallClick overrides

Next Steps