---
title: "CopilotChatMessageView"
description: "Angular standalone component that renders a list of chat messages, routing each message to assistant, user, reasoning, or activity rendering with slot customization."
---
## Overview
`CopilotChatMessageView` renders an array of messages and routes each one to the correct renderer based on its `role`: assistant messages go to [`CopilotChatAssistantMessage`](/reference/angular/components/CopilotChatAssistantMessage), user messages to [`CopilotChatUserMessage`](/reference/angular/components/CopilotChatUserMessage), reasoning messages to the reasoning renderer, and activity messages to any registered activity renderer. It optionally renders a typing cursor at the end of the list while the agent is streaming.
This is the message-list layer used internally by [`CopilotChatView`](/reference/angular/components/CopilotChatView). It mirrors React's `CopilotChatMessageView`. Use it directly when you manage your own `messages` array and want only the list rendering without the surrounding scroll container and input.
The component is standalone and uses `OnPush` change detection. Reactive inputs are Angular [signals](https://angular.dev/guide/signals).
## Usage
Import the component class and use its `copilot-chat-message-view` selector in your template.
```ts title="src/app/messages.component.ts"
import { Component, signal } from "@angular/core";
import { CopilotChatMessageView } from "@copilotkit/angular";
import type { Message } from "@ag-ui/core";
@Component({
selector: "app-messages",
standalone: true,
imports: [CopilotChatMessageView],
template: `
`,
})
export class MessagesComponent {
messages = signal([]);
isLoading = signal(false);
}
```
## Inputs
The messages to render. Each entry is routed by its `role` (`assistant`, `user`, `reasoning`, or `activity`). Entries with any other role are skipped.
Whether to show the typing cursor at the end of the list. The cursor is suppressed when the last message is a reasoning message.
Whether the agent is currently streaming. Forwarded to assistant, reasoning, and activity renderers so they can show in-progress state.
Extra CSS classes merged onto the default list container (`flex flex-col`).
ID of the agent whose messages are being rendered. Used to resolve the matching activity-message renderer and the agent instance passed to it.
### Assistant message slot inputs
A component class to render each assistant message in place of the default [`CopilotChatAssistantMessage`](/reference/angular/components/CopilotChatAssistantMessage).
A template to render each assistant message. Takes precedence over `assistantMessageComponent` when both are set.
Extra CSS classes forwarded to each assistant message renderer.
### User message slot inputs
A component class to render each user message in place of the default [`CopilotChatUserMessage`](/reference/angular/components/CopilotChatUserMessage).
A template to render each user message. Takes precedence over `userMessageComponent` when both are set.
Extra CSS classes forwarded to each user message renderer.
### Cursor slot inputs
A component class to render the typing cursor in place of the default cursor.
A template to render the typing cursor. Takes precedence over `cursorComponent` when both are set.
Extra CSS classes forwarded to the cursor renderer.
## Outputs
These bubble up from the per-message child components so you can observe toolbar interactions from the list level. Each payload is `{ message: Message }`.
Emitted when the thumbs-up action is triggered on an assistant message.
Emitted when the thumbs-down action is triggered on an assistant message.
Emitted when the read-aloud action is triggered on an assistant message.
Emitted when the regenerate action is triggered on an assistant message.
Emitted when a user message is copied.
Emitted when a user message edit action is triggered.
## Custom layout
For full control over how the list is laid out, project a template named `customLayout`. It receives a context object with the current `messages`, the `isLoading` and `showCursor` flags, and `messageElements` (the messages filtered to the renderable roles). When this template is present, the default list rendering is replaced entirely.
```html title="src/app/messages.component.html"
@for (message of messages; track message.id) {
{{ message.content }}
}
@if (showCursor) {
...
}
```
## Customizing message rendering
To swap out how a whole role is rendered without rebuilding the layout, pass a slot input. The slot accepts either a component class or a template, with the template taking precedence.
```ts title="src/app/messages.component.ts"
import { Component, signal } from "@angular/core";
import { CopilotChatMessageView } from "@copilotkit/angular";
import { MyAssistantMessage } from "./my-assistant-message.component";
import type { Message } from "@ag-ui/core";
@Component({
selector: "app-messages",
standalone: true,
imports: [CopilotChatMessageView],
template: `
`,
})
export class MessagesComponent {
messages = signal([]);
protected readonly assistantMessage = MyAssistantMessage;
}
```
## Related
}
/>
}
/>
}
/>