/** * AI SDK UI - Chat with File Attachments * * Demonstrates: * - File upload with experimental_attachments * - Image preview * - Multiple file support * - Sending files with messages * * Requires: * - API route that handles multimodal inputs (GPT-4 Vision, Claude 3.5, etc.) * - experimental_attachments feature (v5) * * Usage: * 1. Set up API route with vision model * 2. Copy this component * 3. Customize file handling as needed */ 'use client'; import { useChat } from 'ai/react'; import { useState, FormEvent } from 'react'; export default function ChatWithAttachments() { const { messages, sendMessage, isLoading, error } = useChat({ api: '/api/chat', }); const [input, setInput] = useState(''); const [files, setFiles] = useState(null); const [previewUrls, setPreviewUrls] = useState([]); // Handle file selection const handleFileChange = (e: React.ChangeEvent) => { const selectedFiles = e.target.files; setFiles(selectedFiles); if (selectedFiles) { // Create preview URLs const urls = Array.from(selectedFiles).map((file) => URL.createObjectURL(file) ); setPreviewUrls(urls); } else { setPreviewUrls([]); } }; // Handle form submission const handleSubmit = (e: FormEvent) => { e.preventDefault(); if (!input.trim() && !files) return; sendMessage({ content: input || 'Please analyze these images', experimental_attachments: files ? Array.from(files).map((file) => ({ name: file.name, contentType: file.type, url: URL.createObjectURL(file), })) : undefined, }); // Clean up setInput(''); setFiles(null); previewUrls.forEach((url) => URL.revokeObjectURL(url)); setPreviewUrls([]); }; // Remove file const removeFile = (index: number) => { if (!files) return; const newFiles = Array.from(files).filter((_, i) => i !== index); const dataTransfer = new DataTransfer(); newFiles.forEach((file) => dataTransfer.items.add(file)); setFiles(dataTransfer.files); // Update preview URLs URL.revokeObjectURL(previewUrls[index]); setPreviewUrls(previewUrls.filter((_, i) => i !== index)); }; return (
{/* Header */}

AI Chat with File Attachments

Upload images and ask questions about them

{/* Messages */}
{messages.map((message) => (
{/* Text content */}
{message.content}
{/* Attachments */} {message.experimental_attachments && message.experimental_attachments.length > 0 && (
{message.experimental_attachments.map( (attachment, idx) => (
{attachment.contentType?.startsWith('image/') ? ( {attachment.name} ) : (
{attachment.name}
)}
) )}
)}
))} {isLoading && (
Processing...
)}
{/* Error */} {error && (
Error: {error.message}
)} {/* File preview */} {previewUrls.length > 0 && (

Selected files ({previewUrls.length}):

{previewUrls.map((url, idx) => (
{`Preview
))}
)} {/* Input */}
{/* File input */} {/* Text input */}
setInput(e.target.value)} placeholder="Ask a question about the images..." disabled={isLoading} className="flex-1 p-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" />
); }