chatkit-frontend

ChatKit Frontend Skill

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "chatkit-frontend" with this command: npx skills add maneeshanif/todo-spec-driven/maneeshanif-todo-spec-driven-chatkit-frontend

ChatKit Frontend Skill

Production-ready skill for implementing OpenAI ChatKit in Next.js applications.

Official Documentation (ALWAYS verify before implementation):

  • OpenAI ChatKit Docs

  • ChatKit.js Docs

  • GitHub Repository

  • Advanced Samples

  • Domain Allowlist - Required for production

Overview

OpenAI ChatKit is a batteries-included framework for building AI-powered chat experiences with:

  • Deep UI Customization - Theme, colors, radius, typography

  • Built-in Streaming - Natural real-time conversations

  • Tool Integration - Display agent actions and reasoning

  • Interactive Widgets - Rich content in chat messages

  • File Handling - Upload and attachment support

  • Thread Management - Conversation history and switching

Architecture

┌─────────────────────────────────────────────────────────────────────────┐ │ Next.js Frontend │ ├─────────────────────────────────────────────────────────────────────────┤ │ │ │ ┌──────────────────┐ ┌──────────────────────────────────────────┐ │ │ │ ConversationSidebar │ │ ChatKit Component │ │ │ │ (Custom) │ │ ┌────────────────────────────────────┐ │ │ │ │ │ │ │ <ChatKit control={control} /> │ │ │ │ │ - Thread list │◄──►│ │ - Messages │ │ │ │ │ - New chat │ │ │ - Input │ │ │ │ │ - Delete/rename │ │ │ - Streaming │ │ │ │ └──────────────────┘ │ │ - Tool indicators │ │ │ │ │ └────────────────────────────────────┘ │ │ │ └──────────────────────────────────────────┘ │ │ │ │ │ ┌───────────────────▼───────────────────┐ │ │ │ useChatKit Hook │ │ │ │ - api: { url, domainKey } │ │ │ │ - theme: { colorScheme, radius } │ │ │ │ - startScreen: { greeting, prompts } │ │ │ │ - onClientTool: (invocation) => {} │ │ │ └───────────────────┬───────────────────┘ │ └──────────────────────────────────────────────┼───────────────────────────┘ │ SSE Stream ┌────────────────────▼────────────────────┐ │ FastAPI Backend │ │ POST /chatkit │ │ - ChatKit-compatible SSE format │ └─────────────────────────────────────────┘

Installation

Step 1: Install ChatKit Package

cd frontend npm install @openai/chatkit-react

Step 2: Verify Installation

Check package.json

grep chatkit package.json

Quick Start

Basic ChatKit Integration

// app/chat/page.tsx 'use client';

import { ChatKit, useChatKit } from '@openai/chatkit-react';

export default function ChatPage() { const { control } = useChatKit({ api: { url: ${process.env.NEXT_PUBLIC_API_URL}/chatkit, domainKey: process.env.NEXT_PUBLIC_OPENAI_DOMAIN_KEY || 'local-dev', }, });

return ( <div className="h-screen w-full"> <ChatKit control={control} className="h-full w-full" /> </div> ); }

With Full Configuration

// app/chat/page.tsx 'use client';

import { ChatKit, useChatKit } from '@openai/chatkit-react'; import { useAuthStore } from '@/stores/auth-store'; import { useConversationStore } from '@/stores/conversation-store';

export default function ChatPage() { const { user } = useAuthStore(); const { currentConversation, refreshConversations } = useConversationStore();

const { control } = useChatKit({ // API Configuration api: { url: ${process.env.NEXT_PUBLIC_API_URL}/chatkit, domainKey: process.env.NEXT_PUBLIC_OPENAI_DOMAIN_KEY || 'local-dev', },

// Theme Configuration
theme: {
  colorScheme: 'light', // 'light' | 'dark' | 'system'
  radius: 'round',      // 'sharp' | 'round' | 'pill'
  color: {
    accent: { primary: '#0066cc', level: 2 },
    grayscale: { hue: 220, tint: 6, shade: -4 },
  },
},

// Start Screen
startScreen: {
  greeting: `Hello${user?.name ? `, ${user.name}` : ''}! How can I help you today?`,
  prompts: [
    'Show my tasks',
    'Add a new task',
    'What tasks are due today?',
    'Mark my grocery task as complete',
  ],
},

// Header Configuration
header: {
  enabled: true,
  title: 'Task Assistant',
},

// Composer Configuration
composer: {
  placeholder: 'Ask about your tasks...',
},

// History (built-in - optional, we use custom sidebar)
history: {
  enabled: false, // Disable built-in, use custom ConversationSidebar
},

// Client-side Tool Handling
onClientTool: async (invocation) => {
  console.log('Client tool invoked:', invocation.name, invocation.params);

  // Handle client-side tools (theme switching, etc.)
  if (invocation.name === 'switch_theme') {
    // Handle theme change
    return { success: true };
  }

  return { success: false };
},

// Error Handling
onError: ({ error }) => {
  console.error('ChatKit error:', error);
},

// Message Events
onMessage: (message) => {
  console.log('New message:', message);
  // Refresh conversations after message
  refreshConversations();
},

});

return ( <div className="h-screen w-full"> <ChatKit control={control} className="h-full w-full max-w-4xl mx-auto" /> </div> ); }

Project Structure

frontend/ ├── app/ │ └── chat/ │ ├── layout.tsx # Chat layout with sidebar │ └── page.tsx # ChatKit page │ ├── components/ │ ├── chat/ │ │ └── ChatKitWrapper.tsx # Optional ChatKit wrapper │ │ │ └── conversation/ # Custom sidebar (keep existing) │ ├── ConversationSidebar.tsx │ ├── ConversationList.tsx │ ├── ConversationItem.tsx │ └── NewChatButton.tsx │ ├── stores/ │ └── conversation-store.ts # Conversation state (keep existing) │ └── lib/ └── chatkit/ └── config.ts # ChatKit configuration utilities

Theming

Dark Mode Support

'use client';

import { ChatKit, useChatKit } from '@openai/chatkit-react'; import { useTheme } from 'next-themes';

export function ThemedChatKit() { const { theme } = useTheme(); const isDark = theme === 'dark';

const { control } = useChatKit({ api: { url: '/chatkit', domainKey: 'local-dev' }, theme: { colorScheme: isDark ? 'dark' : 'light', radius: 'round', color: { grayscale: { hue: 220, tint: 6, shade: isDark ? -1 : -4, }, accent: { primary: isDark ? '#f1f5f9' : '#0f172a', level: 1, }, }, }, });

return <ChatKit control={control} className="h-full w-full" />; }

Tailwind CSS Integration

<ChatKit control={control} className=" h-full w-full [--chatkit-bg:hsl(var(--background))] [--chatkit-text:hsl(var(--foreground))] [--chatkit-primary:hsl(var(--primary))] [--chatkit-border:hsl(var(--border))] " />

Conversation Management

Custom Sidebar with ChatKit

// app/chat/layout.tsx 'use client';

import { ConversationSidebar } from '@/components/conversation/ConversationSidebar';

export default function ChatLayout({ children }: { children: React.ReactNode }) { return ( <div className="flex h-screen"> {/* Custom Conversation Sidebar */} <ConversationSidebar />

  {/* ChatKit Area */}
  &#x3C;div className="flex-1 overflow-hidden">
    {children}
  &#x3C;/div>
&#x3C;/div>

); }

Thread Switching

// When user selects a conversation from sidebar const handleSelectConversation = (conversationId: number) => { // Update URL or state router.push(/chat?thread=${conversationId});

// ChatKit will load the thread automatically if configured };

Environment Variables

Frontend (.env.local)

NEXT_PUBLIC_API_URL=http://localhost:8000

ChatKit Domain Key (REQUIRED for production)

Get from: https://platform.openai.com/settings/organization/security/domain-allowlist

NEXT_PUBLIC_OPENAI_DOMAIN_KEY=your-domain-key-here

Domain Allowlist Configuration (Production)

Note: localhost works without domain allowlist configuration.

Migration from Custom UI

Before (Custom Components)

// OLD: Custom chat interface import { ChatContainer } from '@/components/chat/ChatContainer'; import { MessageList } from '@/components/chat/MessageList'; import { MessageInput } from '@/components/chat/MessageInput';

export default function ChatPage() { return ( <ChatContainer> <MessageList messages={messages} /> <MessageInput onSend={sendMessage} /> </ChatContainer> ); }

After (ChatKit)

// NEW: ChatKit import { ChatKit, useChatKit } from '@openai/chatkit-react';

export default function ChatPage() { const { control } = useChatKit({ api: { url: '/chatkit', domainKey: 'local-dev' }, });

return <ChatKit control={control} className="h-full w-full" />; }

What to Keep

  • ConversationSidebar

  • Better UX than built-in history

  • conversation-store.ts

  • Thread management state

  • Auth integration - User context for ChatKit

What to Remove

  • ChatContainer.tsx

  • Replaced by ChatKit

  • MessageList.tsx

  • Replaced by ChatKit

  • MessageInput.tsx

  • Replaced by ChatKit

  • StreamingMessage.tsx

  • Replaced by ChatKit

  • Custom SSE client (partially) - ChatKit handles streaming

Verification Checklist

  • @openai/chatkit-react installed

  • ChatKit page created at /chat

  • useChatKit hook configured with API URL

  • Theme matches app design system

  • Dark mode works correctly

  • Start screen shows greeting and prompts

  • Custom ConversationSidebar integrated

  • Backend /chatkit endpoint working

  • Streaming responses display correctly

  • Domain allowlist configured (production)

  • Mobile responsive design

Common Issues

ChatKit Not Rendering

// Ensure client-side rendering 'use client';

// Check control is initialized if (!control) return <div>Loading...</div>;

CORS Errors

Backend: Add ChatKit origins to CORS

app.add_middleware( CORSMiddleware, allow_origins=["http://localhost:3000", "https://your-app.vercel.app"], allow_credentials=True, allow_methods=[""], allow_headers=[""], )

SSE Format Issues

Backend: Use correct SSE format for ChatKit

yield f"data: {json.dumps({'type': 'text', 'content': chunk})}\n\n" yield "data: [DONE]\n\n"

See Also

  • REFERENCE.md - Complete API reference

  • examples.md - Full code examples

  • templates/ - Starter templates

  • chatkit-backend skill - Backend integration

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

conversation-management

No summary provided by upstream source.

Repository SourceNeeds Review
General

dapr-integration

No summary provided by upstream source.

Repository SourceNeeds Review
General

kafka-setup

No summary provided by upstream source.

Repository SourceNeeds Review