Skip to main content

Documentation Index

Fetch the complete documentation index at: https://cometchat-22654f5b-react-uikit-v7.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

What is a Plugin?

A plugin owns one or more message types. It tells the UI Kit:
  • How to render the message as a bubble in the message list
  • What context menu options to show when a user hovers/long-presses a message
  • What preview text to display in the Conversations list subtitle
Every message that appears in the UI is rendered by a plugin. If no plugin matches a message type, the message is not displayed.

Where Plugins Are Used

LocationPlugin MethodWhat it does
Message ListrenderBubble()Renders the bubble content (text, image grid, poll, etc.)
Message ListgetOptions()Provides context menu items (reply, edit, delete, copy, react)
Conversations ListgetLastMessagePreview()Returns subtitle text (”📷 Photo”, “You: Hello”, ”🎥 Video”)
Message BubblerenderHeaderView(), renderFooterView(), etc.Customizes bubble regions beyond content

Default Plugins

These plugins are included automatically — no configuration needed:
PluginMessage TypeWhat it renders
TexttextFormatted text with mentions, URLs, markdown
ImageimageImage grid with captions, click-to-fullscreen
VideovideoVideo player with thumbnail
FilefileFile card with download button
AudioaudioWaveform audio player
Pollsextension_pollPoll creation + voting bubble
Stickersextension_stickerSticker image bubble
Collaborative Documentextension_documentDocument collaboration link
Collaborative Whiteboardextension_whiteboardWhiteboard collaboration link
Group ActiongroupMember”User joined”, “User left” system messages
Call Actionaudio, video (call category)“Missed call”, “Call ended” system messages
DeleteAny (deleted)“This message was deleted” placeholder

How Plugin Resolution Works

When the UI Kit needs to render a message, it asks the Plugin Registry to find the right plugin:
  1. If the message is deleted (getDeletedAt() !== null), the Delete plugin handles it
  2. Otherwise, the registry finds the first plugin whose messageTypes includes the message’s type AND whose messageCategories includes the message’s category
  3. First match wins — plugin order matters
Message { type: "image", category: "message" }
  → Registry scans plugins in order
  → CometChatImagePlugin matches (messageTypes: ["image"], messageCategories: ["message"])
  → ImagePlugin.renderBubble() is called

Adding Plugins

Default plugins are always included. To add extra plugins (like AI), pass them via the plugins prop on CometChatProvider:
import { CometChatProvider } from "@cometchat/chat-uikit-react";
import { CometChatAIPlugin } from "@cometchat/chat-uikit-react/plugins/ai";

function App() {
  return (
    <CometChatProvider
      appId="YOUR_APP_ID"
      region="us"
      authKey="YOUR_AUTH_KEY"
      uid="cometchat-uid-1"
      plugins={[CometChatAIPlugin]}
    >
      <MyChatApp />
    </CometChatProvider>
  );
}
Your custom plugins are appended after the defaults. Since first match wins, default plugins take priority for their message types. To override a default plugin, you’d need to use the manual approach with a custom plugin array.

Creating a Custom Plugin

Implement the CometChatMessagePlugin interface. Here’s a minimal “location” message plugin:
import React from "react";
import type { CometChat } from "@cometchat/chat-sdk-javascript";
import type {
  CometChatMessagePlugin,
  CometChatMessagePluginContext,
  CometChatMessageOption,
} from "@cometchat/chat-uikit-react";

export const LocationPlugin: CometChatMessagePlugin = {
  id: "location",
  messageTypes: ["location"],
  messageCategories: ["custom"],

  renderBubble(message: CometChat.BaseMessage, context: CometChatMessagePluginContext) {
    const customMessage = message as CometChat.CustomMessage;
    const data = customMessage.getData() as { customData?: { latitude: number; longitude: number } };
    const { latitude, longitude } = data.customData ?? { latitude: 0, longitude: 0 };

    return React.createElement("div", { className: "location-bubble" },
      React.createElement("img", {
        src: `https://maps.googleapis.com/maps/api/staticmap?center=${latitude},${longitude}&zoom=15&size=300x200&key=YOUR_KEY`,
        alt: "Location",
        style: { borderRadius: 8, width: "100%" },
      }),
      React.createElement("p", { style: { margin: "8px 0 0", fontSize: 12 } },
        `${latitude.toFixed(4)}, ${longitude.toFixed(4)}`
      )
    );
  },

  getOptions(message: CometChat.BaseMessage, context: CometChatMessagePluginContext): CometChatMessageOption[] {
    // Minimal options — just delete for sender
    return [
      {
        id: "delete",
        title: context.getLocalizedString?.("delete") ?? "Delete",
        senderOnly: true,
        onClick: (msg) => context.onDeleteMessage?.(msg),
      },
    ];
  },

  getLastMessagePreview(): string {
    return "📍 Location";
  },
};
Register it:
<CometChatProvider
  appId="YOUR_APP_ID"
  region="us"
  authKey="YOUR_AUTH_KEY"
  uid="cometchat-uid-1"
  plugins={[LocationPlugin]}
>
  <MyChatApp />
</CometChatProvider>
For a complete tutorial with sending, receiving, and styling, see Creating a Custom Plugin.

Plugin Interface Reference

interface CometChatMessagePlugin {
  /** Unique plugin identifier. */
  id: string;

  /** SDK message types this plugin handles (e.g., ["text"], ["image"]). */
  messageTypes: string[];

  /** SDK message categories this plugin handles (e.g., ["message"], ["custom"]). */
  messageCategories: string[];

  /** Render the bubble content for a message. */
  renderBubble(message: BaseMessage, context: PluginContext): ReactNode;

  /** Return context menu options for a message. */
  getOptions?(message: BaseMessage, context: PluginContext): MessageOption[];

  /** Return plain-text preview for the conversation list subtitle. */
  getLastMessagePreview?(message: BaseMessage, loggedInUser: User, t?: (key: string) => string): string;

  /** Return text formatters (only relevant for text plugin). */
  getTextFormatters?(): CometChatTextFormatter[];

  // --- View Slot Methods (optional) ---
  /** Custom leading view (avatar area). */
  renderLeadingView?(message: BaseMessage, context: PluginContext): ReactNode;
  /** Custom header view (sender name area). */
  renderHeaderView?(message: BaseMessage, context: PluginContext): ReactNode;
  /** Custom footer view (reactions area). */
  renderFooterView?(message: BaseMessage, context: PluginContext): ReactNode;
  /** Custom bottom view (moderation area). */
  renderBottomView?(message: BaseMessage, context: PluginContext): ReactNode;
  /** Custom status info view (timestamp + receipts). */
  renderStatusInfoView?(message: BaseMessage, context: PluginContext): ReactNode;
  /** Custom reply view (quoted message preview). */
  renderReplyView?(message: BaseMessage, context: PluginContext): ReactNode;
  /** Custom thread view (reply count indicator). */
  renderThreadView?(message: BaseMessage, context: PluginContext): ReactNode;
}

Plugin Context

The context object passed to every plugin method:
FieldTypeDescription
loggedInUserCometChat.UserThe currently logged-in user
groupCometChat.Group | undefinedThe group (if group chat)
alignment"left" | "right" | "center"Bubble alignment
theme"light" | "dark"Current theme
getLocalizedString(key: string) => stringLocalization function
onDeleteMessage(msg) => voidDelete a message
onEditMessage(msg) => voidEnter edit mode
onReplyMessage(msg) => voidSet reply-to target
onThreadClick(msg) => voidOpen thread view
onReactToMessage(msg) => voidOpen emoji picker
onMessageInfo(msg) => voidOpen message info panel
onMarkAsUnread(msg) => voidMark as unread
onFlagMessage(msg) => voidOpen flag/report dialog
showToast(text) => voidShow a toast notification
getTextFormatters() => Formatter[]Get text formatters for caption rendering
publish(event) => voidPublish a UI event

Next Steps

Text Plugin

Text rendering, mentions, markdown, URLs

Image Plugin

Image grid, captions, fullscreen viewer

Custom Plugin

Build your own plugin from scratch

Text Formatters

URL, mentions, markdown, and custom formatters