Chat UI and customization

Add a full Angular chat, choose its layout, and customize messages, slots, labels, and styles.


CopilotChat gives you a complete chat surface backed by the agent from your Copilot Runtime. It owns message streaming, suggestions, the composer, attachments, transcription, and the active thread.

This guide starts from the provider in the Angular quickstart and shows how to choose and customize the visible chat.

Choose a chat surface#

SurfaceUse it when
CopilotChatChat belongs inside an existing page or panel.
CopilotPopupChat should open from a floating launcher.
CopilotSidebarChat should sit beside the main application or open as an overlay.
CopilotChatViewYou own the agent wiring and only need the chat layout.

All four are standalone Angular components.

Add an inline chat#

Import CopilotChat, give its host a real height, and point it at an agent when you do not want the default agent.

src/app/support-chat.component.ts
import { ChangeDetectionStrategy, Component } from "@angular/core";
import { CopilotChat } from "@copilotkit/angular";

@Component({
  selector: "app-support-chat",
  imports: [CopilotChat],
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <section class="chat-shell" aria-label="Support assistant">
      <copilot-chat agentId="support" />
    </section>
  `,
  styles: `
    .chat-shell {
      height: min(48rem, 80vh);
      overflow: hidden;
      border: 1px solid #dbe3eb;
      border-radius: 1rem;
    }
  `,
})
export class SupportChatComponent {}

Import the package stylesheet once in the application's global stylesheet:

src/styles.css
@import "@copilotkit/angular/styles.css";

Use a popup or sidebar#

Both modal surfaces manage focus, Escape closing, and launcher-focus restore. Their open model supports two-way binding.

src/app/app.component.ts
import { Component, signal } from "@angular/core";
import { CopilotPopup, CopilotSidebar } from "@copilotkit/angular";

@Component({
  selector: "app-root",
  imports: [CopilotPopup, CopilotSidebar],
  template: `
    <copilot-popup
      [(open)]="popupOpen"
      title="Support assistant"
      [clickOutsideToClose]="true"
    />

    <copilot-sidebar
      [(open)]="sidebarOpen"
      mode="docked"
      position="right"
      title="Workspace assistant"
      [width]="480"
    />
  `,
})
export class AppComponent {
  readonly popupOpen = signal(false);
  readonly sidebarOpen = signal(false);
}

Compact viewports render the sidebar as a modal even when mode is "docked". Only one open docked sidebar can own the page margin at a time.

Replace an assistant message#

Pass a standalone component class to assistantMessageComponent. CopilotKit creates it for each assistant message and binds its message input.

src/app/custom-assistant-message.component.ts
import { ChangeDetectionStrategy, Component, input } from "@angular/core";

type AssistantMessage = {
  id: string;
  role: "assistant";
  content?: string;
};

@Component({
  selector: "app-custom-assistant-message",
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <article class="answer">
      <span class="answer__label">Assistant</span>
      <p>{{ message().content }}</p>
    </article>
  `,
})
export class CustomAssistantMessageComponent {
  readonly message = input.required<AssistantMessage>();
}
src/app/support-chat.component.ts
import { Component } from "@angular/core";
import { CopilotChat } from "@copilotkit/angular";
import { CustomAssistantMessageComponent } from "./custom-assistant-message.component";

@Component({
  selector: "app-support-chat",
  imports: [CopilotChat],
  template: `
    <copilot-chat
      [assistantMessageComponent]="assistantMessageComponent"
      assistantMessageClass="support-answer"
    />
  `,
})
export class SupportChatComponent {
  protected readonly assistantMessageComponent =
    CustomAssistantMessageComponent;
}

CopilotChat also accepts component or template slots for reasoning messages, the composer, and content after the transcript. Use CopilotChatView directly when you need its scroll view, disclaimer, feather, input-container, or scroll-to-bottom slots.

Scope CSS changes#

The package stylesheet exposes stable chat classes. Put a scope class on your feature host so the change stays local.

src/styles.css
.support-chat .copilotKitUserMessage {
  color: white;
  background: #2563eb;
  border-radius: 0.75rem;
}

.support-chat .copilotKitAssistantMessage {
  padding: 0.75rem;
  color: #172554;
  background: #eff6ff;
  border-radius: 0.75rem;
}

Next steps#