AI Agent Component Spec
AI Agent Component Spec
Report incorrect code
Copy
Ask AI
{
"component": "CometChatMessageTemplate",
"kind": "model-class",
"package": "@cometchat/chat-uikit-react",
"import": "import { CometChatMessageTemplate } from \"@cometchat/chat-uikit-react\";",
"description": "Data structure defining how message bubbles render in CometChatMessageList. Each template maps a type+category pair to view functions.",
"usage": "Pass an array of CometChatMessageTemplate instances to CometChatMessageList via the templates prop.",
"properties": {
"type": { "type": "string", "required": true, "description": "CometChat message type" },
"category": { "type": "string", "default": "\"\"", "description": "CometChat message category" },
"headerView": { "type": "function | null", "default": "null", "description": "Custom header view function" },
"contentView": { "type": "function | null", "default": "null", "description": "Custom content view function" },
"footerView": { "type": "function | null", "default": "null", "description": "Custom footer view function" },
"bottomView": { "type": "function | null", "default": "null", "description": "Custom bottom view function" },
"bubbleView": { "type": "function | null", "default": "null", "description": "Replaces entire bubble" },
"statusInfoView": { "type": "function | null", "default": "null", "description": "Custom status info view function" },
"replyView": { "type": "function | null", "default": "null", "description": "Custom reply preview function" },
"options": { "type": "function", "description": "Returns action sheet items for long-press" }
},
"relatedComponents": ["CometChatMessageList"]
}
Overview
Message templates let you customize how different message types render in your chat. You can modify individual parts of a message bubble (header, content, footer) or replace the entire bubble for specific message types. Time estimate: 20 minutesDifficulty: Intermediate
Prerequisites
- React.js integration completed
- Messaging guide completed
- Understanding of CometChat message types
Steps
Step 1: Understand the bubble structure
A message bubble has these customizable slots:| View | Default | Purpose |
|---|---|---|
headerView | Sender name | Top of bubble |
contentView | Message content | Main body |
footerView | Reactions | Below content |
bottomView | Link previews | Bottom section |
statusInfoView | Receipt + timestamp | Status area |
replyView | Reply preview | Reply context |
bubbleView | Entire bubble | Replaces all above |
Step 2: Get existing templates
Retrieve the built-in templates and modify specific ones:Report incorrect code
Copy
Ask AI
import { useState, useEffect } from "react";
import {
CometChatMessageList,
CometChatMessageTemplate,
CometChatUIKit,
CometChatUIKitConstants,
} from "@cometchat/chat-uikit-react";
import { CometChat } from "@cometchat/chat-sdk-javascript";
function CustomTemplateDemo() {
const [chatGroup, setChatGroup] = useState<CometChat.Group>();
const [templates, setTemplates] = useState<CometChatMessageTemplate[]>([]);
useEffect(() => {
CometChat.getGroup("guid").then((group) => setChatGroup(group));
// Get all built-in templates
const allTemplates = CometChatUIKit.getDataSource().getAllMessageTemplates();
setTemplates(allTemplates);
}, []);
if (!chatGroup) return null;
return <CometChatMessageList group={chatGroup} templates={templates} />;
}
Step 3: Customize the header view
Add a status badge to the sender name:Report incorrect code
Copy
Ask AI
import { useState, useEffect } from "react";
import {
CometChatMessageList,
CometChatUIKit,
CometChatUIKitConstants,
CometChatMessageTemplate,
} from "@cometchat/chat-uikit-react";
import { CometChat } from "@cometchat/chat-sdk-javascript";
function HeaderViewDemo() {
const [chatGroup, setChatGroup] = useState<CometChat.Group>();
const [templates, setTemplates] = useState<CometChatMessageTemplate[]>([]);
useEffect(() => {
CometChat.getGroup("guid").then((group) => setChatGroup(group));
const definedTemplates = CometChatUIKit.getDataSource().getAllMessageTemplates();
const modified = definedTemplates.map((t) => {
if (
t.type === CometChatUIKitConstants.MessageTypes.text &&
t.category === CometChatUIKitConstants.MessageCategory.message
) {
t.headerView = (message: CometChat.BaseMessage) => (
<>{message.getSender().getName()} • 🗓️ In meeting</>
);
}
return t;
});
setTemplates(modified);
}, []);
if (!chatGroup) return null;
return <CometChatMessageList group={chatGroup} templates={templates} />;
}

Step 4: Create a custom content view
Build a product card for custom message types:- TypeScript
- CSS
Report incorrect code
Copy
Ask AI
import { useState, useEffect } from "react";
import {
CometChatMessageList,
CometChatUIKit,
CometChatUIKitConstants,
CometChatMessageTemplate,
} from "@cometchat/chat-uikit-react";
import { CometChat } from "@cometchat/chat-sdk-javascript";
function ContentViewDemo() {
const [chatGroup, setChatGroup] = useState<CometChat.Group>();
const [templates, setTemplates] = useState<CometChatMessageTemplate[]>([]);
useEffect(() => {
CometChat.getGroup("guid").then((group) => setChatGroup(group));
const definedTemplates = CometChatUIKit.getDataSource().getAllMessageTemplates();
const CUSTOM_MESSAGE_TYPE = "product";
const customTemplate = new CometChatMessageTemplate({
type: CUSTOM_MESSAGE_TYPE,
category: CometChatUIKitConstants.MessageCategory.custom,
contentView: (message: CometChat.BaseMessage) => (
<div className="product-card">
<div className="product-card__body">
<div className="product-card__title">Blazer Casual</div>
<div className="product-card__description">
Men's Tailored Regular Fit Blazer
</div>
<div className="product-card__price">
$37.99 <span className="product-card__price-old">$74.00</span>
</div>
</div>
<div className="product-card__footer">Buy now</div>
</div>
),
});
definedTemplates.push(customTemplate);
setTemplates(definedTemplates);
}, []);
const getMessageRequestBuilder = () => {
const CUSTOM_MESSAGE_TYPE = "product";
const categories = CometChatUIKit.getDataSource().getAllMessageCategories();
categories.push(CometChatUIKitConstants.MessageCategory.custom);
const types = CometChatUIKit.getDataSource().getAllMessageTypes();
types.push(CUSTOM_MESSAGE_TYPE);
return new CometChat.MessagesRequestBuilder()
.setCategories(categories)
.setTypes(types)
.hideReplies(true)
.setLimit(30);
};
if (!chatGroup) return null;
return (
<CometChatMessageList
group={chatGroup}
templates={templates}
messagesRequestBuilder={getMessageRequestBuilder()}
/>
);
}
Report incorrect code
Copy
Ask AI
.product-card__body {
height: 105px;
display: flex;
padding: 12px 4px;
flex-direction: column;
text-align: left;
gap: 16px;
}
.product-card__title {
color: #141414;
font: 700 16px/1.2 Roboto;
}
.product-card__description {
color: #727272;
font: 400 14px/1.2 Roboto;
}
.product-card__price {
color: #6852d6;
font: 700 16px/1.2 Roboto;
}
.product-card__price-old {
color: #727272;
font: 400 14px/1.2 Roboto;
text-decoration: line-through;
}
.product-card__footer {
display: flex;
height: 40px;
padding: 8px 20px;
justify-content: center;
align-items: center;
border-top: 1px solid #dcdcdc;
color: #6852d6;
font: 500 14px/1.2 Roboto;
}

Step 5: Replace the entire bubble
For complete control, usebubbleView to replace the whole message:
- TypeScript
- CSS
Report incorrect code
Copy
Ask AI
import { useState, useEffect } from "react";
import {
CometChatMessageList,
CometChatUIKit,
CometChatUIKitConstants,
CometChatMessageTemplate,
MessageBubbleAlignment,
CometChatUIKitLoginListener,
isMessageSentByMe,
} from "@cometchat/chat-uikit-react";
import { CometChat } from "@cometchat/chat-sdk-javascript";
function BubbleViewDemo() {
const [chatGroup, setChatGroup] = useState<CometChat.Group>();
const [templates, setTemplates] = useState<CometChatMessageTemplate[]>([]);
useEffect(() => {
CometChat.getGroup("guid").then((group) => setChatGroup(group));
const definedTemplates = CometChatUIKit.getDataSource().getAllMessageTemplates();
const modified = definedTemplates.map((t) => {
if (
t.type === CometChatUIKitConstants.MessageTypes.text &&
t.category === CometChatUIKitConstants.MessageCategory.message
) {
t.bubbleView = (
message: CometChat.BaseMessage,
alignment: MessageBubbleAlignment
) => {
const isSentByMe = isMessageSentByMe(
message,
CometChatUIKitLoginListener.getLoggedInUser()!
);
let textMessage = "";
if (message instanceof CometChat.TextMessage) {
textMessage = message.getText();
}
return (
<div className={`custom-bubble ${isSentByMe ? "outgoing" : "incoming"}`}>
<div className="custom-bubble__text">{textMessage}</div>
</div>
);
};
}
return t;
});
setTemplates(modified);
}, []);
if (!chatGroup) return null;
return <CometChatMessageList group={chatGroup} templates={templates} />;
}
Report incorrect code
Copy
Ask AI
.custom-bubble {
display: flex;
flex-direction: column;
width: 100%;
padding: 20px;
gap: 12px;
}
.custom-bubble.outgoing {
align-items: flex-end;
}
.custom-bubble.incoming {
align-items: flex-start;
}
.custom-bubble__text {
max-width: 60%;
padding: 4px;
border-radius: 2px 2px 0px 2px;
background: #6852d6;
color: white;
}
.custom-bubble.incoming .custom-bubble__text {
background-color: #e8e8e8;
color: #141414;
}

Step 6: Customize action sheet options
Add custom actions to the message long-press menu:Report incorrect code
Copy
Ask AI
import { useState, useEffect } from "react";
import {
CometChatMessageList,
CometChatUIKit,
CometChatUIKitConstants,
CometChatMessageTemplate,
CometChatActionsIcon,
} from "@cometchat/chat-uikit-react";
import { CometChat } from "@cometchat/chat-sdk-javascript";
function OptionsDemo() {
const [chatGroup, setChatGroup] = useState<CometChat.Group>();
const [templates, setTemplates] = useState<CometChatMessageTemplate[]>([]);
useEffect(() => {
CometChat.getGroup("guid").then((group) => setChatGroup(group));
const definedTemplates = CometChatUIKit.getDataSource().getAllMessageTemplates();
const modified = definedTemplates.map((t) => {
if (
t.type === CometChatUIKitConstants.MessageTypes.text &&
t.category === CometChatUIKitConstants.MessageCategory.message
) {
t.options = (
loggedInUser: CometChat.User,
message: CometChat.BaseMessage,
group?: CometChat.Group
) => {
const defaultOptions: any =
CometChatUIKit.getDataSource().getMessageOptions(loggedInUser, message, group);
const customAction: any = new CometChatActionsIcon({
id: "bookmark",
title: "Bookmark",
iconURL: "",
onClick: () => console.log("Bookmarked:", message.getId()),
});
defaultOptions.splice(1, 0, customAction);
return defaultOptions;
};
}
return t;
});
setTemplates(modified);
}, []);
if (!chatGroup) return null;
return <CometChatMessageList group={chatGroup} templates={templates} />;
}

Complete Example
Report incorrect code
Copy
Ask AI
import { useState, useEffect } from "react";
import {
CometChatMessageList,
CometChatMessageTemplate,
CometChatUIKit,
CometChatUIKitConstants,
MessageBubbleAlignment,
} from "@cometchat/chat-uikit-react";
import { CometChat } from "@cometchat/chat-sdk-javascript";
function CustomizedMessageList() {
const [chatGroup, setChatGroup] = useState<CometChat.Group>();
const [templates, setTemplates] = useState<CometChatMessageTemplate[]>([]);
useEffect(() => {
CometChat.getGroup("YOUR_GROUP_GUID").then((group) => setChatGroup(group));
const allTemplates = CometChatUIKit.getDataSource().getAllMessageTemplates();
// Customize text messages
const modified = allTemplates.map((t) => {
if (
t.type === CometChatUIKitConstants.MessageTypes.text &&
t.category === CometChatUIKitConstants.MessageCategory.message
) {
// Add status to header
t.headerView = (message: CometChat.BaseMessage) => (
<span style={{ fontSize: 12, color: "#666" }}>
{message.getSender().getName()} • Online
</span>
);
// Add warning to bottom
t.bottomView = (message: CometChat.BaseMessage) => (
<div style={{ fontSize: 11, color: "#f44649", padding: "4px 8px" }}>
⚠️ Message expires in 24 hours
</div>
);
}
return t;
});
setTemplates(modified);
}, []);
if (!chatGroup) return null;
return (
<div style={{ height: "100vh" }}>
<CometChatMessageList group={chatGroup} templates={templates} />
</div>
);
}
export default CustomizedMessageList;
Advanced: Custom message type template
Advanced: Custom message type template
Create a template for a completely new message type:
Report incorrect code
Copy
Ask AI
const CUSTOM_TYPE = "location";
const locationTemplate = new CometChatMessageTemplate({
type: CUSTOM_TYPE,
category: CometChatUIKitConstants.MessageCategory.custom,
contentView: (message: CometChat.BaseMessage) => {
const data = message.getData() as { lat: number; lng: number };
return (
<div style={{ padding: 12 }}>
<img
src={`https://maps.googleapis.com/maps/api/staticmap?center=${data.lat},${data.lng}&zoom=14&size=200x150&key=YOUR_KEY`}
alt="Location"
/>
<div>📍 Shared location</div>
</div>
);
},
});
// Add to templates array
allTemplates.push(locationTemplate);
Common Issues
When using
bubbleView, all other view slots (headerView, contentView, etc.) are ignored for that template.| Issue | Solution |
|---|---|
| Custom template not showing | Ensure type and category match exactly |
| Custom messages not loading | Add type to MessagesRequestBuilder |
| Styles not applying | Check CSS specificity, use .cometchat prefix |