Skip to main content
Custom plugins let you handle any message type with your own rendering logic. This walkthrough builds a complete “Location” plugin that renders a map preview, provides context menu options, and shows a conversation preview.

Step 1: Define the Plugin

Create a file that implements CometChatMessagePlugin:
src/plugins/LocationPlugin.tsx

Step 2: Register the Plugin

Pass your plugin to CometChatProvider:
src/App.tsx
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":

Step 4: Style the Bubble

src/plugins/LocationPlugin.css

Plugin Interface Reference

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

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)
  • A single plugin can handle multiple types — like the Call Action plugin handles both audio and video in the call category