chatkit-frontend
3
总安装量
3
周安装量
#55604
全站排名
安装命令
npx skills add https://github.com/maneeshanif/todo-spec-driven --skill chatkit-frontend
Agent 安装分布
gemini-cli
3
github-copilot
3
codex
3
kimi-cli
3
cursor
3
amp
3
Skill 文档
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 */}
<div className="flex-1 overflow-hidden">
{children}
</div>
</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)
- Deploy frontend to get production URL (e.g.,
https://your-app.vercel.app) - Go to: https://platform.openai.com/settings/organization/security/domain-allowlist
- Add your production domain
- Copy domain key to
NEXT_PUBLIC_OPENAI_DOMAIN_KEY
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 historyconversation-store.ts– Thread management state- Auth integration – User context for ChatKit
What to Remove
ChatContainer.tsx– Replaced by ChatKitMessageList.tsx– Replaced by ChatKitMessageInput.tsx– Replaced by ChatKitStreamingMessage.tsx– Replaced by ChatKit- Custom SSE client (partially) – ChatKit handles streaming
Verification Checklist
-
@openai/chatkit-reactinstalled - ChatKit page created at
/chat -
useChatKithook configured with API URL - Theme matches app design system
- Dark mode works correctly
- Start screen shows greeting and prompts
- Custom ConversationSidebar integrated
- Backend
/chatkitendpoint 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