Skip to main content
The CopilotSidebar component provides a slide-out sidebar interface for AI agent interactions. It includes a toggle button and smooth animations, perfect for applications that need persistent access to AI without taking up main content space.

Basic Usage

import { CopilotSidebar } from "@copilotkit/react-core";

function App() {
  return (
    <div>
      <main>
        {/* Your app content */}
      </main>
      
      <CopilotSidebar />
    </div>
  );
}

Props

CopilotSidebar accepts all CopilotChat props plus:
defaultOpen
boolean
Whether the sidebar is open by default. Defaults to false.
width
number | string
Width of the sidebar. Can be a number (pixels) or CSS string. Defaults to 400 (400px).
header
React.ReactElement
Custom header component to display at the top of the sidebar.
toggleButton
React.ReactElement
Custom toggle button component. If not provided, a default button is rendered.
All other CopilotChat props are supported:
  • agentId
  • threadId
  • labels
  • onError
  • welcomeScreen
  • messageView
  • suggestionView
  • And more…

Examples

Basic Sidebar

import { CopilotSidebar } from "@copilotkit/react-core";

function App() {
  return (
    <div>
      <header>
        <h1>My Application</h1>
      </header>
      
      <main>
        <p>Your content here</p>
      </main>
      
      <CopilotSidebar />
    </div>
  );
}

Custom Width

import { CopilotSidebar } from "@copilotkit/react-core";

function WiderSidebar() {
  return (
    <div>
      <main>Content</main>
      
      {/* 500px wide sidebar */}
      <CopilotSidebar width={500} />
    </div>
  );
}

function ResponsiveSidebar() {
  return (
    <div>
      <main>Content</main>
      
      {/* 40% of viewport width */}
      <CopilotSidebar width="40vw" />
    </div>
  );
}

Open by Default

import { CopilotSidebar } from "@copilotkit/react-core";

function DefaultOpenSidebar() {
  return (
    <div>
      <main>Content</main>
      
      <CopilotSidebar 
        defaultOpen={true}
        width={450}
      />
    </div>
  );
}

Custom Header

import { CopilotSidebar } from "@copilotkit/react-core";

function CustomHeaderSidebar() {
  return (
    <div>
      <main>Content</main>
      
      <CopilotSidebar
        header={
          <div style={{ 
            padding: "20px", 
            borderBottom: "1px solid #eee",
            background: "#f8f9fa"
          }}>
            <h2>AI Assistant</h2>
            <p>How can I help you today?</p>
          </div>
        }
      />
    </div>
  );
}

Custom Toggle Button

import { CopilotSidebar } from "@copilotkit/react-core";
import { MessageSquare } from "lucide-react";

function CustomToggleSidebar() {
  return (
    <div>
      <main>Content</main>
      
      <CopilotSidebar
        toggleButton={
          <button
            style={{
              position: "fixed",
              bottom: "20px",
              right: "20px",
              width: "60px",
              height: "60px",
              borderRadius: "50%",
              background: "#007bff",
              color: "white",
              border: "none",
              cursor: "pointer",
              boxShadow: "0 4px 12px rgba(0,0,0,0.15)"
            }}
          >
            <MessageSquare size={24} />
          </button>
        }
      />
    </div>
  );
}

With Agent Selection

import { CopilotSidebar } from "@copilotkit/react-core";
import { useState } from "react";

function MultiAgentSidebar() {
  const [agent, setAgent] = useState("default");
  
  return (
    <div>
      <main>
        <h1>Multi-Agent App</h1>
        <div>
          <button onClick={() => setAgent("default")}>
            General Assistant
          </button>
          <button onClick={() => setAgent("research")}>
            Research Agent
          </button>
        </div>
      </main>
      
      <CopilotSidebar
        agentId={agent}
        header={
          <div style={{ padding: "16px" }}>
            <h3>
              {agent === "default" ? "General Assistant" : "Research Agent"}
            </h3>
          </div>
        }
      />
    </div>
  );
}

Custom Styling

import { CopilotSidebar } from "@copilotkit/react-core";

function StyledSidebar() {
  return (
    <div>
      <main>Content</main>
      
      <CopilotSidebar
        className="custom-sidebar"
        messageView={{ className: "custom-message" }}
        width={480}
        header={
          <div className="sidebar-header">
            <img src="/logo.png" alt="Logo" />
            <h2>AI Assistant</h2>
          </div>
        }
      />
    </div>
  );
}

// In your CSS:
// .custom-sidebar { 
//   background: linear-gradient(180deg, #fff 0%, #f8f9fa 100%);
// }
// .sidebar-header {
//   display: flex;
//   align-items: center;
//   gap: 12px;
//   padding: 20px;
// }

Mobile Responsive

import { CopilotSidebar } from "@copilotkit/react-core";
import { useMediaQuery } from "@/hooks/useMediaQuery";

function ResponsiveSidebar() {
  const isMobile = useMediaQuery("(max-width: 768px)");
  
  return (
    <div>
      <main>Content</main>
      
      <CopilotSidebar
        width={isMobile ? "100vw" : 400}
        defaultOpen={!isMobile}
      />
    </div>
  );
}

With Labels

import { CopilotSidebar } from "@copilotkit/react-core";

function LocalizedSidebar() {
  return (
    <div>
      <main>Content</main>
      
      <CopilotSidebar
        labels={{
          inputPlaceholder: "Escribe tu pregunta...",
          stopGenerating: "Detener"
        }}
        header={
          <div style={{ padding: "16px" }}>
            <h2>Asistente de IA</h2>
          </div>
        }
      />
    </div>
  );
}

Animation Behavior

The sidebar includes smooth animations:
  • Slides in from the right when opened
  • Slides out to the right when closed
  • Animates the backdrop/overlay
  • Smooth transitions (300ms duration)

Backdrop

When open, the sidebar displays a semi-transparent backdrop that:
  • Darkens the main content
  • Closes the sidebar when clicked
  • Prevents interaction with background content

Position

The sidebar is positioned:
  • Fixed to the right edge of the viewport
  • Takes full viewport height
  • Stacks above other content (high z-index)
  • Does not affect document flow

Best Practices

Set Appropriate Width

Choose a width that works for your content. 400-500px is typical for desktop. Use responsive values for mobile.

Provide Clear Header

Add a custom header to give users context about the AI assistant’s purpose and capabilities.

Consider Mobile

On mobile devices, consider using full viewport width or switching to CopilotPopup for better UX.

Consistent Positioning

Place the toggle button in a consistent, easily accessible location (typically bottom-right).

Keyboard Navigation

The sidebar supports keyboard interaction:
  • Press Escape to close the sidebar
  • Tab through interactive elements
  • Focus is trapped within the sidebar when open

Accessibility

Built-in accessibility features:
  • ARIA labels for toggle button
  • Focus management when opening/closing
  • Screen reader announcements
  • Keyboard navigation support

Performance

The sidebar is optimized for performance:
  • Renders chat content only when open
  • Lazy loads messages as needed
  • Efficient animation using CSS transforms
  • Minimal re-renders

Integration with Layout

The sidebar works with common layout patterns:
import { CopilotSidebar } from "@copilotkit/react-core";

function AppLayout() {
  return (
    <div className="app-layout">
      <nav className="sidebar-nav">
        {/* Left navigation */}
      </nav>
      
      <main className="content">
        {/* Main content */}
      </main>
      
      {/* Right sidebar for AI */}
      <CopilotSidebar />
    </div>
  );
}

Comparison with Other Components

FeatureCopilotSidebarCopilotChatCopilotPopup
PositioningRight edge, full heightEmbeddedBottom-right, floating
ToggleBuilt-in buttonNoneBuilt-in button
BackdropYesNoYes
Best forDesktop appsFull-screen chatQuick interactions
MobileTakes full widthResponsiveBetter mobile UX

TypeScript

interface CopilotSidebarProps extends CopilotChatProps {
  defaultOpen?: boolean;
  width?: number | string;
  header?: React.ReactElement;
  toggleButton?: React.ReactElement;
}