# 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) => (
))}
```
**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