A complete, production-ready chat interface component for AI conversations.
Overview
The ChatInterface component provides:
- Message history display
- Input field with send button
- Streaming support
- Error handling
- Loading states
- Responsive design
Basic Usage
import ChatInterface from "@/components/ai/ChatInterface";
import type { ChatMessageProps } from "@/components/ai/ChatMessage";
export default function ChatPage() {
const [messages, setMessages] = useState<ChatMessageProps[]>([]);
const [isLoading, setIsLoading] = useState(false);
const [isTyping, setIsTyping] = useState(false);
const handleSendMessage = async (message: string) => {
// Your message sending logic
setIsLoading(true);
// ... send to API
setIsLoading(false);
};
return (
<div className="min-h-screen p-4">
<ChatInterface
messages={messages}
isLoading={isLoading}
isTyping={isTyping}
onSendMessage={handleSendMessage}
/>
</div>
);
}
Props
interface ChatInterfaceProps {
messages: ChatMessageProps[]; // Required: Array of messages to display
isLoading?: boolean; // Show loading state on send button
isTyping?: boolean; // Show typing indicator
disabled?: boolean; // Disable input (e.g., no subscription)
placeholder?: string; // Input placeholder text
onSendMessage: (message: string) => void; // Required: Handler for sending messages
inputValue?: string; // Controlled input value (optional)
onInputChange?: (value: string) => void; // Controlled input change handler (optional)
}
Examples
Basic Chat
const [messages, setMessages] = useState<ChatMessageProps[]>([]);
<ChatInterface
messages={messages}
onSendMessage={handleSendMessage}
/>
With Loading States
<ChatInterface
messages={messages}
isLoading={isSending}
isTyping={isStreaming}
onSendMessage={handleSendMessage}
/>
With Custom Placeholder
<ChatInterface
messages={messages}
placeholder="Ask your AI assistant..."
onSendMessage={handleSendMessage}
/>
Disabled for Non-Subscribers
<ChatInterface
messages={messages}
disabled={!hasSubscription}
placeholder={hasSubscription ? "Ask a question..." : "Upgrade to continue chatting"}
onSendMessage={handleSendMessage}
/>
Controlled Input
const [inputValue, setInputValue] = useState("");
<ChatInterface
messages={messages}
inputValue={inputValue}
onInputChange={setInputValue}
onSendMessage={handleSendMessage}
/>
Integration with ChatSidebar
The component is designed to work with ChatSidebar:
import ChatSidebar from "@/components/ai/ChatSidebar";
import ChatInterface from "@/components/ai/ChatInterface";
export default function ChatPage() {
return (
<div className="flex h-screen">
<ChatSidebar
currentConversationId={conversationId}
onSelectConversation={handleSelect}
onNewConversation={handleNew}
/>
<div className="flex-1">
<ChatInterface
messages={messages}
isTyping={isTyping}
onSendMessage={handleSend}
/>
</div>
</div>
);
}
Message Format
Messages follow this structure:
interface Message {
role: "user" | "assistant";
content: string;
timestamp?: Date;
id?: string;
}
State Management
The component manages:
- Message history
- Input state
- Loading state
- Error state
- Streaming state (if enabled)
Error Handling
The component handles:
- Network errors
- API errors
- Authentication errors
- Subscription access errors
Errors are displayed as user-friendly messages.
Accessibility
- Keyboard navigation - Enter to send, Escape to cancel
- Screen reader support - Proper ARIA labels
- Focus management - Auto-focus on input
- Error announcements - Accessible error messages
Best Practices
- Wrap in authenticated route - Ensure user is logged in
- Show subscription status - Display subscription status alongside chat
- Handle errors gracefully - Provide clear error messages
- Optimize for mobile - Test on mobile devices
- Limit message history - Prevent memory issues
Advanced Usage
Custom Message Renderer
const CustomMessage = ({ message }: { message: Message }) => {
return (
<div className={`message ${message.role}`}>
<div className="avatar">
<img src={message.role === "user" ? userAvatar : aiAvatar} />
</div>
<div className="content">{message.content}</div>
</div>
);
};
<ChatInterface
messageRenderer={CustomMessage}
/>
Integration with State Management
import { useChatStore } from "@/store/chat";
export default function ChatPage() {
const { messages, addMessage } = useChatStore();
return (
<ChatInterface
initialMessages={messages}
onMessageSent={(msg) => addMessage({ role: "user", content: msg })}
/>
);
}
Next Steps
- Learn about Subscription Status
- Explore Typing Indicator
- Check out AI Features