💬 Build Your Chat Interface
Now let’s connect your frontend to your backend and create a simple chat interface. You’ll build everything in one component to keep it simple and focused on the AI functionality.
🎨 Create the Chat Component
Section titled “🎨 Create the Chat Component”Replace the contents of your src/App.jsx
with this complete chat interface:
import { useState } from 'react'import { Send, Bot, User } from 'lucide-react'
function App() { const [messages, setMessages] = useState([]) const [input, setInput] = useState('') const [loading, setLoading] = useState(false)
const sendMessage = async () => { if (!input.trim()) return
const userMessage = { text: input, isUser: true } setMessages(prev => [...prev, userMessage]) setInput('') setLoading(true)
try { const response = await fetch('http://localhost:8000/api/chat', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ message: input }), })
const data = await response.json()
if (data.success) { const aiMessage = { text: data.response, isUser: false } setMessages(prev => [...prev, aiMessage]) } else { const errorMessage = { text: 'Sorry, something went wrong.', isUser: false } setMessages(prev => [...prev, errorMessage]) } } catch (error) { console.error('Error:', error) const errorMessage = { text: 'Failed to connect to server.', isUser: false } setMessages(prev => [...prev, errorMessage]) } finally { setLoading(false) } }
const handleKeyPress = (e) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault() sendMessage() } }
return ( <div className="min-h-screen bg-gray-100 flex items-center justify-center p-4"> <div className="bg-white rounded-lg shadow-lg w-full max-w-2xl h-[600px] flex flex-col"> {/* Header */} <div className="bg-blue-500 text-white p-4 rounded-t-lg"> <h1 className="text-xl font-bold">AI Chat Assistant</h1> <p className="text-blue-100">Ask me anything!</p> </div>
{/* Messages */} <div className="flex-1 overflow-y-auto p-4 space-y-4"> {messages.length === 0 && ( <div className="text-center text-gray-500 mt-20"> <Bot className="w-12 h-12 mx-auto mb-4 text-gray-400" /> <p>Start a conversation with your AI assistant!</p> </div> )}
{messages.map((message, index) => ( <div key={index} className={`flex items-start space-x-3 ${ message.isUser ? 'justify-end' : 'justify-start' }`} > {!message.isUser && ( <div className="bg-blue-500 p-2 rounded-full"> <Bot className="w-4 h-4 text-white" /> </div> )}
<div className={`max-w-xs lg:max-w-md px-4 py-2 rounded-lg ${ message.isUser ? 'bg-blue-500 text-white' : 'bg-gray-200 text-gray-800' }`} > {message.text} </div>
{message.isUser && ( <div className="bg-gray-500 p-2 rounded-full"> <User className="w-4 h-4 text-white" /> </div> )} </div> ))}
{loading && ( <div className="flex items-start space-x-3"> <div className="bg-blue-500 p-2 rounded-full"> <Bot className="w-4 h-4 text-white" /> </div> <div className="bg-gray-200 text-gray-800 px-4 py-2 rounded-lg"> <div className="flex space-x-1"> <div className="w-2 h-2 bg-gray-500 rounded-full animate-bounce"></div> <div className="w-2 h-2 bg-gray-500 rounded-full animate-bounce" style={{animationDelay: '0.1s'}}></div> <div className="w-2 h-2 bg-gray-500 rounded-full animate-bounce" style={{animationDelay: '0.2s'}}></div> </div> </div> </div> )} </div>
{/* Input */} <div className="border-t p-4"> <div className="flex space-x-2"> <input type="text" value={input} onChange={(e) => setInput(e.target.value)} onKeyPress={handleKeyPress} placeholder="Type your message..." className="flex-1 border border-gray-300 rounded-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500" disabled={loading} /> <button onClick={sendMessage} disabled={loading || !input.trim()} className="bg-blue-500 hover:bg-blue-600 disabled:bg-gray-300 text-white p-2 rounded-lg transition-colors" > <Send className="w-5 h-5" /> </button> </div> </div> </div> </div> )}
export default App
🔍 Understanding the Chat Component
Section titled “🔍 Understanding the Chat Component”Let’s break down what this component does:
State Management
Section titled “State Management”const [messages, setMessages] = useState([])const [input, setInput] = useState('')const [loading, setLoading] = useState(false)
What each state does:
messages
- Stores all chat messages (both user and AI)input
- Controls the text input fieldloading
- Shows when you’re waiting for AI response
Sending Messages
Section titled “Sending Messages”const sendMessage = async () => { // Add user message to chat const userMessage = { text: input, isUser: true } setMessages(prev => [...prev, userMessage])
// Call your backend API const response = await fetch('http://localhost:8000/api/chat', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ message: input }), })}
What this does:
- Adds user message to the chat immediately
- Sends message to your Node.js backend
- Handles the AI response and adds it to chat
UI Features
Section titled “UI Features”- Message bubbles - Different styles for user vs AI messages
- Loading animation - Bouncing dots while waiting for AI
- Enter to send - Press Enter to send messages
- Icons - Bot and User icons for visual clarity
- Responsive design - Works on mobile and desktop
🚀 Test Your Chat App
Section titled “🚀 Test Your Chat App”- Start your backend (in your
node-backend
folder):
npm run dev
- Start your frontend (in your
chat-frontend
folder):
npm run dev
-
Open your browser to
http://localhost:5173
-
Try sending a message like:
- “Hello, how are you?”
- “Write a short poem about coding”
- “Explain React in simple terms”
You should see your messages appear instantly, and AI responses come back from your backend!
🔧 Troubleshooting
Section titled “🔧 Troubleshooting”Issue | Fix |
---|---|
CORS errors in browser | Make sure your backend has cors() middleware |
Network errors | Check that backend is running on port 8000 |
Messages not sending | Open browser dev tools to see error details |
Styling looks wrong | Make sure Tailwind CSS is properly installed |
Loading state stuck | Check your backend console for errors |
🎉 Success!
Section titled “🎉 Success!”Congratulations! You’ve built a complete AI chat application that:
- ✅ Connects React frontend to Node.js backend
- ✅ Sends messages to OpenAI’s API
- ✅ Shows real-time responses
- ✅ Has a clean, simple UI
- ✅ Handles errors gracefully
✅ What’s Next
Section titled “✅ What’s Next”Your basic chat app is working! Next, you’ll add more advanced features like:
- Message history persistence
- Streaming responses for faster replies
- File upload capabilities
- Better error handling
You’ve built your first AI-powered application! 🎊