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.
Overview
Custom plugins let you handle any message type with your own rendering logic. This guide walks through building a complete “Location” plugin that:
- Renders a map preview bubble
- Provides context menu options
- Shows a preview in the conversations list
Step 1: Define the Plugin
Create a file for your plugin that implements CometChatMessagePlugin:
src/plugins/LocationPlugin.tsx
import React from "react";
import type { CometChat } from "@cometchat/chat-sdk-javascript";
import type {
CometChatMessagePlugin,
CometChatMessagePluginContext,
CometChatMessageOption,
} from "@cometchat/chat-uikit-react";
// Extract location data from the custom message
function getLocationData(message: CometChat.BaseMessage) {
const customMessage = message as CometChat.CustomMessage;
const data = customMessage.getCustomData() as {
latitude?: number;
longitude?: number;
address?: string;
} | undefined;
return {
latitude: data?.latitude ?? 0,
longitude: data?.longitude ?? 0,
address: data?.address ?? "",
};
}
export const LocationPlugin: CometChatMessagePlugin = {
id: "location",
messageTypes: ["location"],
messageCategories: ["custom"],
renderBubble(message: CometChat.BaseMessage, context: CometChatMessagePluginContext) {
const { latitude, longitude, address } = getLocationData(message);
const mapUrl = `https://maps.googleapis.com/maps/api/staticmap?center=${latitude},${longitude}&zoom=15&size=300x200&markers=${latitude},${longitude}&key=YOUR_API_KEY`;
return (
<div className="location-bubble">
<img
src={mapUrl}
alt={address || "Location"}
style={{ borderRadius: 8, width: "100%", maxWidth: 300 }}
/>
{address && (
<p style={{ margin: "8px 0 0", fontSize: 13, color: "#666" }}>
{address}
</p>
)}
<a
href={`https://maps.google.com/?q=${latitude},${longitude}`}
target="_blank"
rel="noopener noreferrer"
style={{ fontSize: 12, color: "#6851FF" }}
>
Open in Maps
</a>
</div>
);
},
getOptions(
message: CometChat.BaseMessage,
context: CometChatMessagePluginContext
): CometChatMessageOption[] {
const options: CometChatMessageOption[] = [];
// Copy coordinates
options.push({
id: "copy-location",
title: "Copy Location",
onClick: (msg) => {
const { latitude, longitude } = getLocationData(msg);
void navigator.clipboard.writeText(`${latitude}, ${longitude}`);
context.showToast?.("Location copied to clipboard");
},
});
// Delete (sender only)
options.push({
id: "delete",
title: context.getLocalizedString?.("delete") ?? "Delete",
senderOnly: true,
onClick: (msg) => context.onDeleteMessage?.(msg),
});
return options;
},
getLastMessagePreview(
message: CometChat.BaseMessage
): string {
const { address } = getLocationData(message);
return address ? `📍 ${address}` : "📍 Location";
},
};
Step 2: Register the Plugin
Pass your plugin to CometChatProvider:
import { CometChatProvider } from "@cometchat/chat-uikit-react";
import { LocationPlugin } from "./plugins/LocationPlugin";
function App() {
return (
<CometChatProvider
appId="YOUR_APP_ID"
region="us"
authKey="YOUR_AUTH_KEY"
uid="cometchat-uid-1"
plugins={[LocationPlugin]}
>
<MyChatApp />
</CometChatProvider>
);
}
Your plugin is appended after the default plugins. Since resolution is first-match, default plugins handle their types first, and your plugin handles "location" messages.
Step 3: Send a Location Message
Use the CometChat SDK to send a custom message with type "location":
import { CometChat } from "@cometchat/chat-sdk-javascript";
import { CometChatUIKit } from "@cometchat/chat-uikit-react";
async function sendLocation(receiverUid: string, lat: number, lng: number) {
const message = new CometChat.CustomMessage(
receiverUid,
CometChat.RECEIVER_TYPE.USER,
"location",
{ latitude: lat, longitude: lng, address: "123 Main St" }
);
await CometChatUIKit.sendCustomMessage(message);
}
Step 4: Style the Bubble
Add CSS for your bubble:
src/plugins/LocationPlugin.css
.location-bubble {
padding: 4px;
max-width: 300px;
}
.location-bubble img {
display: block;
border-radius: 8px;
}
Plugin Interface Quick Reference
interface CometChatMessagePlugin {
id: string; // Unique identifier
messageTypes: string[]; // SDK message types to handle
messageCategories: string[]; // SDK message categories to handle
// Required
renderBubble(message, context): ReactNode;
// Optional
getOptions?(message, context): MessageOption[];
getLastMessagePreview?(message, loggedInUser, t?): string;
getTextFormatters?(): CometChatTextFormatter[];
// View slot overrides (optional)
renderLeadingView?(message, context): ReactNode;
renderHeaderView?(message, context): ReactNode;
renderFooterView?(message, context): ReactNode;
renderBottomView?(message, context): ReactNode;
renderStatusInfoView?(message, context): ReactNode;
renderReplyView?(message, context): ReactNode;
renderThreadView?(message, context): ReactNode;
}
Tips
- Lazy-load heavy components — use
React.lazy() + Suspense for bubble components that import large libraries
- Use
context.getLocalizedString — for any user-facing text in options or bubbles
- Return
[] from getOptions — for system messages that shouldn’t have a context menu
- Keep
getLastMessagePreview short — max ~100 characters, plain text only (no HTML)
- Test with
messageTypes array — a single plugin can handle multiple types (like the Call Action plugin handles both audio and video in the call category)