Skip to main content
View Slots let you swap out specific parts of a component — the avatar area, title, subtitle, trailing section, or the entire row — while keeping the rest of the component’s behavior intact.

The Builder Callback Pattern

Flutter UI Kit components accept nullable builder callbacks for each customizable region. Each callback receives the relevant data model and returns a Widget?. Return null to fall back to the default view.
Widget? Function(BuildContext context, DataModel model)?

Available View Slots

List Components (Conversations, Users, Groups, Group Members)

PropertyRegionSignature
leadingViewLeft section (avatar)Widget? Function(BuildContext, Model)
titleViewTitle textWidget? Function(BuildContext, Model)
subtitleViewSubtitle textWidget? Function(BuildContext, Model)
trailingViewRight section (timestamp, badge)Widget? Function(BuildContext, Model)

Message List

PropertyRegionSignature
headerViewAbove the message listWidget? Function(BuildContext, {User?, Group?, int?})
footerViewBelow the message listWidget? Function(BuildContext, {User?, Group?, int?})
templatesAll message bubble templatesList<CometChatMessageTemplate>
addTemplateAdditional templates merged with defaultsList<CometChatMessageTemplate>

Message Template Slots

Each CometChatMessageTemplate has its own view slots for the bubble structure:
PropertyRegionSignature
headerViewAbove the bubble contentWidget? Function(BaseMessage, BuildContext, BubbleAlignment)
contentViewMain bubble contentWidget? Function(BaseMessage, BuildContext, BubbleAlignment, {AdditionalConfigurations?})
footerViewBelow the bubbleWidget? Function(BaseMessage, BuildContext, BubbleAlignment)
bottomViewBelow the content, inside the bubbleWidget? Function(BaseMessage, BuildContext, BubbleAlignment)
statusInfoViewTimestamp and receiptsWidget? Function(BaseMessage, BuildContext, BubbleAlignment)
replyViewQuoted reply previewWidget? Function(BaseMessage, BuildContext, BubbleAlignment)
threadViewThread reply indicatorWidget? Function(BaseMessage, BuildContext, BubbleAlignment)
bubbleViewEntire bubble (replaces all other slots)Widget? Function(BaseMessage, BuildContext, BubbleAlignment)

Example: Custom Leading View on Conversations

CometChatConversations(
  leadingView: (context, conversation) {
    final name = conversation.conversationWith?.name ?? '';
    return CircleAvatar(
      backgroundColor: Color(0xFF6851D6),
      child: Text(
        name.isNotEmpty ? name[0].toUpperCase() : '?',
        style: TextStyle(color: Colors.white, fontSize: 18),
      ),
    );
  },
)

Example: Custom Subtitle View on Conversations

CometChatConversations(
  subtitleView: (context, conversation) {
    final lastMessage = conversation.lastMessage;
    String subtitle;
    if (lastMessage is TextMessage) {
      subtitle = lastMessage.text;
    } else if (lastMessage is MediaMessage) {
      subtitle = '📎 ${lastMessage.attachment?.fileExtension ?? "Media"}';
    } else {
      subtitle = 'New conversation';
    }
    return Text(
      subtitle,
      maxLines: 1,
      overflow: TextOverflow.ellipsis,
    );
  },
)

Example: Custom Header View on Message List

CometChatMessageList(
  user: user,
  headerView: (context, {user, group, parentMessageId}) {
    return Container(
      padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
      color: Color(0xFFEDEAFA),
      child: Row(
        children: [
          Chip(label: Text('📌 Pinned Messages')),
          SizedBox(width: 8),
          Chip(label: Text('🔗 Saved Links')),
        ],
      ),
    );
  },
)

Slot-Level vs Full Replacement

Use individual slot properties (leadingView, titleView, subtitleView, trailingView) when you want to customize one region while keeping the default layout for everything else. Use bubbleView on a CometChatMessageTemplate when you need complete control over the entire message bubble.
When you set bubbleView on a template, all other template slots (headerView, contentView, footerView, etc.) are ignored since the entire bubble is replaced.