skills/react-core/references/chat-components.md
This skill builds on copilotkit/provider-setup. Read it first — every
chat component must be inside CopilotKitProvider.
All chat components live on @copilotkit/react-core/v2. The legacy
@copilotkit/react-ui package is v1-only; its /v2 subpath is a CSS-only
import.
"use client";
import { CopilotChat } from "@copilotkit/react-core/v2";
import "@copilotkit/react-core/v2/styles.css";
export function ChatPanel() {
return <CopilotChat agentId="default" />;
}
<CopilotChat> manages messages, input, streaming, attachments, and
suggestions internally via useAgent. You do not pass messages or
isRunning — they are managed for you.
import { CopilotPopup } from "@copilotkit/react-core/v2";
<CopilotPopup agentId="default" isModalDefaultOpen={false} />;
import { CopilotSidebar } from "@copilotkit/react-core/v2";
<CopilotSidebar agentId="default">
<MainAppContent />
</CopilotSidebar>;
Use CopilotChatView plus the individual slot components when you need
full control over messages, input, or layout. This is the path when you
want to manage messages/isRunning yourself.
import {
CopilotChatView,
CopilotChatInput,
CopilotChatMessageView,
useAgent,
useCopilotKit,
} from "@copilotkit/react-core/v2";
export function HeadlessChat() {
const { agent } = useAgent({ agentId: "default" });
const { copilotkit } = useCopilotKit();
return (
<CopilotChatView
messages={agent.messages}
isRunning={agent.isRunning}
onSubmitInput={async (text) => {
agent.addMessage({
id: crypto.randomUUID(),
role: "user",
content: text,
});
await copilotkit.runAgent({ agent });
}}
>
<CopilotChatMessageView />
<CopilotChatInput />
</CopilotChatView>
);
}
<CopilotChat
agentId="default"
labels={{
chatInputPlaceholder: "Ask about the data…",
thinking: "Analyzing…",
}}
/>
CopilotPanelWrong:
import { CopilotPanel } from "@copilotkit/react-core/v2";
Correct:
import {
CopilotChat,
CopilotPopup,
CopilotSidebar,
CopilotChatView,
} from "@copilotkit/react-core/v2";
CopilotPanel does not exist in v2 (or v1). This is a common hallucination.
The four chat surfaces are CopilotChat, CopilotPopup, CopilotSidebar,
and the headless CopilotChatView.
Source: packages/react-core/src/v2/components/chat/index.ts (no CopilotPanel export)
@copilotkit/react-ui in v2Wrong:
import { CopilotPopup } from "@copilotkit/react-ui";
import "@copilotkit/react-ui/styles.css";
Correct:
import { CopilotPopup } from "@copilotkit/react-core/v2";
import "@copilotkit/react-core/v2/styles.css";
@copilotkit/react-ui is v1 only. The v2 subpath of react-ui is a
CSS-only import — the components are not there. All v2 chat components ship
from @copilotkit/react-core/v2.
Source: packages/react-ui/src/v2/index.ts (CSS-only); v2 migration guide
messages or isRunning to <CopilotChat>Wrong:
<CopilotChat agentId="default" messages={myMessages} isRunning={busy} />
Correct:
// CopilotChat manages messages and isRunning internally.
<CopilotChat agentId="default" />
// For manual control, drop down to headless CopilotChatView:
<CopilotChatView
messages={myMessages}
isRunning={busy}
onSubmitInput={handleSubmit}
>
<CopilotChatMessageView />
<CopilotChatInput />
</CopilotChatView>
CopilotChatProps explicitly Omits messages and isRunning — passing
them is a TypeScript error, and <CopilotChat> always reads from its
internal useAgent call.
Source: packages/react-core/src/v2/components/chat/CopilotChat.tsx:37-52
<CopilotChat> with the same agentId + threadIdWrong:
<CopilotChat agentId="research" threadId="t1" />
<CopilotChat agentId="research" threadId="t1" />
Correct:
// Either use distinct threadIds...
<CopilotChat agentId="research" threadId="panel-a" />
<CopilotChat agentId="research" threadId="panel-b" />
// ...or mount only one <CopilotChat> instance per agent/thread.
Both components resolve to the same per-thread clone (cached in a
module-level WeakMap) and submit duplicate messages. See agent-access for
the clone semantics.
Source: packages/react-core/src/v2/hooks/use-agent.tsx:78-119
Wrong:
import { CopilotChat } from "@copilotkit/react-core/v2";
// …no styles imported
Correct:
import { CopilotChat } from "@copilotkit/react-core/v2";
import "@copilotkit/react-core/v2/styles.css";
The chat components ship unstyled without the v2 stylesheet. Import it once at the root of the app or in the same file that sets up the provider.
Source: packages/react-core/src/v2/index.ts:3 (imports ./index.css)