# Les 14: AI Chat Interface & Streaming --- ## Hoofdstuk **Deel 4: Advanced AI & Deployment** (Les 13-18) ## Beschrijving Bouwen van professionele chat interfaces met streaming responses. Message rendering, markdown support, error handling, loading states, en UX patterns voor AI-powered features. --- ## Te Behandelen (~45 min) - Chat UI patterns en best practices - useChat hook deep dive (state, loading, error) - Streaming response handling en real-time updates - Message rendering strategies en optimizations - Markdown rendering in chat messages - Error handling en error boundaries - Loading states en skeleton loaders - User input validation and sanitization - Accessibility in chat interfaces (ARIA labels) - Message persistence (localStorage of database) - Performance optimization --- ### useChat Hook Deep Dive **State management met useChat:** ```typescript 'use client' import { useChat } from 'ai/react' export function ChatComponent() { const { messages, // All messages in conversation input, // Current input text handleInputChange, // Update input handleSubmit, // Send message isLoading, // Is AI responding? error, // Any errors? } = useChat({ api: '/api/chat', initialMessages: [], // Optional: pre-load messages }) return ( <>
{messages.map((msg) => (
{msg.role}: {msg.content}
))}
{isLoading &&
AI is thinking...
} {error &&
Error: {error.message}
}
) } ``` --- ### Message Rendering Patterns **Basic pattern:** ```typescript
{messages.map((msg) => (
{msg.content}
))}
``` **With markdown rendering:** ```typescript import ReactMarkdown from 'react-markdown'
{msg.content}
``` **With message types:** ```typescript {messages.map((msg) => (
{msg.content}
))} ``` --- ### Error Handling **Structured error handling:** ```typescript try { const response = await fetch('/api/chat', { method: 'POST', body: JSON.stringify({ messages }), }) if (!response.ok) { throw new Error(`API error: ${response.status}`) } // Handle streaming... } catch (error) { console.error('Chat error:', error) setError({ message: 'Failed to send message', code: error instanceof Error ? error.message : 'unknown' }) } ``` **Error boundary:** ```typescript Chat error occurred}> ``` --- ### Loading States **Skeleton loader:** ```typescript function MessageSkeleton() { return (
) } {isLoading && } ``` --- ### Input Validation **Validate before sending:** ```typescript function handleSubmit(e: React.FormEvent) { e.preventDefault() // Trim whitespace const trimmedInput = input.trim() // Validate non-empty if (!trimmedInput) { setError('Message cannot be empty') return } // Validate length if (trimmedInput.length > 1000) { setError('Message too long (max 1000 chars)') return } // Send message handleSubmit(e) } ``` --- ### Message Persistence **Save to localStorage:** ```typescript const [messages, setMessages] = useState(() => { const saved = localStorage.getItem('chat_history') return saved ? JSON.parse(saved) : [] }) // Save whenever messages change useEffect(() => { localStorage.setItem('chat_history', JSON.stringify(messages)) }, [messages]) ``` **Save to database:** ```typescript const saveMessage = async (message: Message) => { await fetch('/api/messages', { method: 'POST', body: JSON.stringify({ content: message.content, role: message.role, userId: user.id, }), }) } ``` --- ## Tools - Vercel AI SDK - React Markdown - Cursor - TypeScript --- ## Lesopdracht (2 uur, klassikaal) ### Build Professional Chat Interface **Groepsdiscussie (15 min):** Bespreek klassikaal de Vercel AI SDK ervaringen uit Les 13 - welke tool calling patterns werkten goed? **Deel 1: Chat Component (45 min)** Build components/ChatInterface.tsx: 1. Use useChat hook 2. Render messages with proper styling 3. User vs AI message styling 4. Input form with validation 5. Tailwind + shadcn/ui components **Deel 2: Markdown & Error Handling (30 min)** 1. Install react-markdown: `npm install react-markdown` 2. Render AI responses with markdown 3. Add error boundary 4. Show error messages to user 5. Proper loading states **Deel 3: UX Improvements (30 min)** 1. Auto-scroll to latest message 2. Disable input while loading 3. Show message count/token usage 4. Add clear chat history button 5. Save messages to localStorage **Deel 4: Testing (15 min)** Test chat interface locally with various inputs and error scenarios. ### Deliverable - Werkende chat interface component - Markdown rendering working - Error handling implemented - LocalStorage persistence - GitHub commit with chat UI --- ## Huiswerk (2 uur) ### Integrate Chat into Your Project **Deel 1: Project Integration (1 uur)** 1. Add chat component to your app 2. Connect to your API route with tools 3. Style to match your design 4. Test with actual tools/integrations 5. Fix any bugs **Deel 2: Enhanced Features (30 min)** Add one of these: - Message copy button - Regenerate response option - Clear history confirmation - Export chat history - Message timestamps **Deel 3: Performance & Polish (30 min)** 1. Optimize re-renders (useMemo, useCallback) 2. Virtual scrolling for long chats 3. Better accessibility (keyboard nav) 4. Mobile responsive tweaks 5. Update docs/AI-DECISIONS.md ### Deliverable - Chat fully integrated in project - Enhanced features implemented - Performance optimized - GitHub commits with improvements --- ## Leerdoelen Na deze les kan de student: - useChat hook volledig begrijpen en gebruiken - Professionele chat UI patterns implementeren - Markdown rendering in chat messages - Error handling en error boundaries toepassen - Loading states en skeletons bouwen - User input valideren en sanitizen - Message persistence (localStorage/DB) - Accessibility in chat interfaces verbeteren - Performance optimizations toepassen - Complete chat feature in Next.js app integreren