CopilotThreadsDrawer
Vue 3 threads drawer that lists and manages conversations next to CopilotChat
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.
Overview
CopilotThreadsDrawer renders the prebuilt conversation drawer beside CopilotChat. It is a thin Vue wrapper around the framework-agnostic <copilotkit-threads-drawer> custom element and stays SSR-safe by loading that element only on mount. The drawer reads from useThreads, follows the surrounding chat configuration when one is present, and lets the user switch, start, archive, unarchive, delete, and filter threads.
When onThreadSelect and onNewThread are omitted, the wrapper drives the surrounding chat configuration directly: selecting a row calls setActiveThreadId(threadId, { explicit: true }), and the "New Conversation" action resets the chat with startNewThread(). Provide those callbacks only if you want to control the active thread yourself.
Thread rename is not exposed in the drawer row menu. Use useThreads for headless rename support.
The threads drawer requires a license. When it is not licensed, the component renders the locked state and keeps the thread store disabled. Visit copilotkit.ai/pricing for details.
Import
<script setup lang="ts">
import { CopilotThreadsDrawer } from "@copilotkit/vue/v2";
import "@copilotkit/vue/styles.css";
</script>Props
Prop
Type
Prop
Type
Prop
Type
Prop
Type
Prop
Type
Prop
Type
Prop
Type
Prop
Type
Prop
Type
Prop
Type
Events
The Vue wrapper emits the following events.
| Event | Payload | Fired when |
|---|---|---|
collapse-change | collapsed: boolean | The desktop collapse state changes |
Slots
Vue uses named slots in place of React render props. CopilotThreadsDrawer only defines one scoped Vue slot; everything else is projected into the underlying custom element with a slot attribute.
Prop
Type
Light-DOM children with these slot names are projected into the drawer:
| Slot | Replaces |
|---|---|
header | The drawer header region |
empty | The empty-state body |
footer | A footer region |
memories | The reserved memories surface |
launcher-icon | The icon inside the mobile launcher |
licensed | The licensed upsell content |
Style the shadow DOM with ::part(). The drawer exposes the usual structural and action parts, including the root, header, list, row, menu, new-thread button, section heading, filter controls, collapse controls, launcher, load-more, fetch-more-error, and licensed surfaces.
Usage
Basic usage
Wrap the drawer and CopilotChat in a shared CopilotChatConfigurationProvider so they operate on the same active thread. This example includes the surrounding CopilotKitProvider, so it is runnable as shown.
<script setup lang="ts">
import {
CopilotChat,
CopilotChatConfigurationProvider,
CopilotKitProvider,
CopilotThreadsDrawer,
} from "@copilotkit/vue/v2";
import "@copilotkit/vue/styles.css";
</script>
<template>
<CopilotKitProvider runtime-url="http://localhost:8200/api/copilotkit">
<CopilotChatConfigurationProvider agent-id="support">
<div class="flex h-full">
<CopilotThreadsDrawer agent-id="support" />
<CopilotChat agent-id="support" />
</div>
</CopilotChatConfigurationProvider>
</CopilotKitProvider>
</template>Custom row and projected chrome
<script setup lang="ts">
import { CopilotThreadsDrawer } from "@copilotkit/vue/v2";
</script>
<template>
<CopilotThreadsDrawer label="History">
<span slot="header">My conversations</span>
<span slot="empty">No threads yet.</span>
<template #row="{ thread }">
<strong>{{ thread.name ?? "New conversation" }}</strong>
</template>
</CopilotThreadsDrawer>
</template>Observing collapse state
<script setup lang="ts">
import { CopilotThreadsDrawer } from "@copilotkit/vue/v2";
function onCollapseChange(collapsed: boolean) {
console.log("drawer collapsed:", collapsed);
}
</script>
<template>
<CopilotThreadsDrawer @collapse-change="onCollapseChange" />
</template>Behavior
- The drawer registers itself with the surrounding chat configuration so the mobile launcher can appear.
- When callbacks are omitted, selecting a row calls
setActiveThreadIdand "New Conversation" callsstartNewThread. - Archive, unarchive, delete, and pagination all flow through
useThreads. - The drawer stays inert while unlicensed, which keeps the thread store from fetching until licensing resolves.
- Rename is headless only; use
useThreads().renameThread()if you need that action. - The wrapper is SSR-safe because the custom element is imported lazily on the client.
Related
CopilotChat- the chat surface this drawer usually drivesCopilotChatConfigurationProvider- shared configuration contextuseThreads- the headless thread data and mutation layer