CSS Customization
Theme CopilotKit Vue components with CSS design tokens.
Open your coding agent in your project's folder, or in an empty folder for a new app.This runs in a coding agent on your computer.
What is this?#
CopilotKit Vue has several plain-CSS ways to change the appearance of the prebuilt UI without changing its behavior. You can:
- Override the v2 design tokens to re-tint the whole UI.
- Scope those tokens to one chat surface so they do not leak across the app.
- Add structural CSS around stable CopilotKit roots and your own slot markup.
- Change inherited fonts per surface.
- Replace icons through Vue slots and user-facing copy through
labels.
The Vue v2 components ship a Tailwind v4 theme based on the standard
shadcn/ui token set. Import the package stylesheet once, then override CSS
custom properties on [data-copilotkit] or an ancestor.
Use slots when you need to replace markup, and headless UI when you need your own surface.
Scoping the theme#
import "@copilotkit/vue/styles.css";The components mark their roots with data-copilotkit. Put a class around one
product area and scope every override below it when the rest of the application
uses different tokens:
<script setup lang="ts">
import { CopilotChat } from "@copilotkit/vue/v2";
</script>
<template>
<section class="support-chat">
<CopilotChat agent-id="support" />
</section>
</template>
<style>
.support-chat [data-copilotkit] {
--primary: oklch(0.55 0.22 264);
--primary-foreground: oklch(0.99 0 0);
--background: oklch(1 0 0);
--foreground: oklch(0.145 0 0);
--muted: oklch(0.97 0 0);
--border: oklch(0.922 0 0);
--radius: 0.625rem;
}
</style>CSS Variables (Easiest)#
The easiest customization is a CSS-variable override because every nested Vue chat component picks it up automatically.
Vue uses the v2 token system
The older --copilot-kit-* variables and .copilotKit... classes documented
for @copilotkit/react-ui style v1 React components do not style
@copilotkit/vue/v2. Vue's public stylesheet is
@copilotkit/vue/styles.css and uses the v2 tokens below.
v2 Design Tokens (shadcn)#
The tokens are scoped to [data-copilotkit] and wired into the prefixed
Tailwind utilities through an @theme inline block. Override them on the
CopilotKit root or any ancestor, just as you would in a shadcn project.
Reference#
These are the most commonly overridden tokens. Each light value has a matching
dark-mode value under .dark [data-copilotkit]. The full set lives in
@copilotkit/vue/styles.css.
| Token | Description |
|---|---|
--background / --foreground | Base surface and primary text. |
--primary / --primary-foreground | Action color and text on it. |
--secondary / --secondary-foreground | Secondary panels and cards. |
--muted / --muted-foreground | Subtle backgrounds and de-emphasized text. |
--accent / --accent-foreground | Hover and active state colors. |
--border / --input / --ring | Dividers, input outline, and focus ring. |
--destructive / --destructive-foreground | Error and danger states. |
--card / --popover (and -foreground) | Elevated surfaces. |
--sidebar-* | Sidebar-specific background, foreground, border, and ring tokens. |
--radius | Base corner radius; the smaller and larger radii derive from it. |
The stylesheet recognizes a .dark ancestor. Override the same tokens under
that ancestor to match your application's dark-mode switch:
.dark [data-copilotkit] {
--background: oklch(0.145 0 0);
--foreground: oklch(0.985 0 0);
--border: oklch(0.269 0 0);
}Any valid CSS color works; oklch() is the default because it preserves
perceived lightness more consistently across hues.
Custom CSS#
Use your own wrapper classes and slot markup for structural changes. Vue v2's internal prefixed utility classes are implementation details, so avoid copying or overriding them as an API. Stable CopilotKit roots and your own classes make safer selectors:
.support-chat [data-copilotkit] {
border-radius: 1rem;
}
.support-chat .support-message-card {
border: 1px solid var(--border);
padding: 1rem;
}Use slots to introduce
.support-message-card or to replace structure. The Vue package does not
expose the v1 React .copilotKitMessages, .copilotKitInput, or
.copilotKitUserMessage class contract.
Custom Fonts#
Fonts inherit through the CopilotKit root, so scope a font to one surface or set it for every Vue chat:
.support-chat [data-copilotkit] {
font-family: Inter, ui-sans-serif, system-ui, sans-serif;
}Custom Icons#
Vue uses slots instead of an icons prop. CopilotPopup and
CopilotSidebar expose a toggle-button slot with open state and actions, so
you can replace the launcher and its icons together:
<CopilotPopup>
<template #toggle-button="{ isOpen, toggle }">
<button type="button" :aria-label="isOpen ? 'Close chat' : 'Open chat'" @click="toggle">
<MyCloseIcon v-if="isOpen" />
<MyChatIcon v-else />
</button>
</template>
</CopilotPopup>The public CopilotChatToggleButton leaf also exposes open-icon and
close-icon slots when you want to keep the default button behavior.
Custom Labels#
Customize user-facing copy through the labels prop:
<CopilotChat
:labels="{
welcomeMessageText: 'Hello! How can I help you today?',
modalHeaderTitle: 'My Copilot',
chatInputPlaceholder: 'Ask me anything!',
}"
/>