---
title: CopilotChatMessageView
description: "Message list container component"
---
`CopilotChatMessageView` is the default component used by [CopilotChat](/reference/copilot-chat) to render the message list. It handles rendering user messages, assistant messages, activity messages, and custom message renderers with optimized memoization for performance.
## What is CopilotChatMessageView?
The CopilotChatMessageView component:
- Renders the conversation message list
- Handles user, assistant, and activity message types
- Supports custom message renderers for extensibility
- Optimizes re-renders with memoization
- Shows a typing cursor during streaming responses
- Built on the [slot system](/reference/slot-system) for deep customization
## Component Architecture
CopilotChatMessageView provides slots for customizing message rendering:
```mermaid
graph LR
MV[CopilotChatMessageView] --> assistantMessage
MV --> userMessage
MV --> cursor
```
### Slot Descriptions
| Slot | Description |
| ------------------ | ----------------------------------------------- |
| `assistantMessage` | Component for rendering assistant (AI) messages |
| `userMessage` | Component for rendering user messages |
| `cursor` | Typing indicator shown during streaming |
## Basic Usage
Customize the message view through the `messageView` prop on [CopilotChat](/reference/copilot-chat):
```tsx
```
## Slot Customization
CopilotChatMessageView uses the [slot system](/reference/slot-system). Each slot accepts four types of values:
1. **Tailwind class string** - Add or override CSS classes
2. **Props object** - Pass additional props to the default component
3. **Custom component** - Replace the component entirely
4. **Nested sub-slots** - Drill down to customize child components
### Assistant Message Customization
The `assistantMessage` slot controls how AI responses are rendered:
```tsx
sendFeedback(message.id, "positive"),
onThumbsDown: (message) => sendFeedback(message.id, "negative"),
onRegenerate: (message) => regenerateResponse(message.id),
},
}}
/>
```
#### Assistant Message Sub-Slots
| Sub-Slot | Description |
| ------------------ | ------------------------------------------------- |
| `markdownRenderer` | Renders the message content with markdown support |
| `toolbar` | Container for action buttons |
| `copyButton` | Button to copy message content |
| `thumbsUpButton` | Positive feedback button |
| `thumbsDownButton` | Negative feedback button |
| `readAloudButton` | Text-to-speech button |
| `regenerateButton` | Button to regenerate the response |
| `toolCallsView` | Renders tool call executions |
For full details, see [CopilotChatAssistantMessage](/reference/copilot-chat-assistant-message).
### User Message Customization
The `userMessage` slot controls how user messages are rendered:
```tsx
editMessage(message),
},
}}
/>
```
#### User Message Sub-Slots
| Sub-Slot | Description |
| ------------------ | ------------------------------------ |
| `messageRenderer` | Renders the message text content |
| `toolbar` | Container for action buttons |
| `copyButton` | Button to copy message content |
| `editButton` | Button to edit the message |
| `branchNavigation` | Navigation for conversation branches |
For full details, see [CopilotChatUserMessage](/reference/copilot-chat-user-message).
### Cursor Customization
The cursor appears while the AI is generating a response:
```tsx
```
Or with a custom component:
```tsx
function CustomCursor() {
return (
);
}
;
```
## Replacing the Message View
To completely replace the message view with your own component, pass a custom component to the `messageView` prop:
```tsx
import { CopilotChatMessageView } from "@copilotkit/react-core";
function CustomMessageView({ messages, isRunning, ...props }) {
return (
{messages.length} messages
{/* Use the default implementation with customizations */}
{isRunning && (
AI is thinking...
)}
);
}
;
```
### Using the Render Function
For even more control, use the children render function pattern:
```tsx
function CustomMessageView({ messages, isRunning }) {
return (
{({ messageElements, messages, isRunning }) => (