In today’s digital world, chat applications are essential for communication. Whether for customer support, community engagement, or simply keeping in touch, having a chat feature can significantly enhance user interaction. In this blog, we’ll build a real-time chat application using Node.js and React, two powerful technologies that allow for dynamic, scalable applications.
Prerequisites
Before we begin, ensure you have the following installed on your system:
- Node.js: Download and install from nodejs.org.
- npm: Comes with Node.js.
- Basic knowledge of JavaScript and React: Familiarity with these concepts will help you understand the code
Setting Up the Project
Step 1: Create a new directory for your project
Open your terminal and run the following commands:
mkdir chat-app cd chat-ap
Step 2: Initialize a new Node.js project
Create a package.json file:
npm init -y
Step 3: Install required packages
We need Express for the server, Socket.io for real-time communication, and CORS for handling cross-origin requests.
npm install express socket.io cors
Step 4: Set up the server
Create a file named server.js
and add the following code:
const express = require('express'); const http = require('http'); const socketIO = require('socket.io'); const cors = require('cors'); const app = express(); const server = http.createServer(app); const io = socketIO(server, { cors: { origin: 'http://localhost:3000', // Your React app URL methods: ['GET', 'POST'], }, }); app.use(cors()); // Object to store connected users and messages let users = {}; let messages = []; // Socket.io connection handling io.on('connection', (socket) => { console.log('User connected:', socket.id); // Handle user joining socket.on('join', (username) => { users[socket.id] = username; socket.broadcast.emit('userConnected', username); io.emit('userList', Object.values(users)); console.log(`${username} joined the chat`); }); // Handle sending messages socket.on('message', (message) => { messages.push({ user: users[socket.id], text: message }); io.emit('message', { user: users[socket.id], text: message }); console.log(`Message from ${users[socket.id]}: ${message}`); }); // Handle disconnecting users socket.on('disconnect', () => { console.log('User disconnected:', socket.id); const username = users[socket.id]; delete users[socket.id]; socket.broadcast.emit('userDisconnected', username); io.emit('userList', Object.values(users)); }); }); // Server listening on defined port const PORT = process.env.PORT || 5000; server.listen(PORT, () => { console.log(`Server is running on port ${PORT}`); });
Frontend Development
Step 1: Set up the React application
Create a React app in the same directory:
npx create-react-app client cd client
Step 2: Install Socket.io client
In the client directory, install the Socket.io client library:
npm install socket.io-client
Step 3: Create the chat application component
In the src
directory, replace the contents of App.js
with the following code:
import React, { useState, useEffect } from 'react'; import io from 'socket.io-client'; import './App.css'; const socket = io('http://localhost:5000'); // Your backend URL function App() { const defaultUsername = 'Guest'; // Default username for all users const [message, setMessage] = useState(''); const [chat, setChat] = useState([]); const [users, setUsers] = useState([]); useEffect(() => { // Automatically join the chat with default username socket.emit('join', defaultUsername); socket.on('message', (payload) => { setChat((prevChat) => [...prevChat, payload]); }); socket.on('userList', (userList) => { setUsers(userList); }); socket.on('userConnected', (username) => { setChat((prevChat) => [ ...prevChat, { user: 'System', text: `${username} has joined the chat` }, ]); }); socket.on('userDisconnected', (username) => { setChat((prevChat) => [ ...prevChat, { user: 'System', text: `${username} has left the chat` }, ]); }); return () => { socket.off(); }; }, []); const sendMessage = (e) => { e.preventDefault(); if (message) { socket.emit('message', message); setMessage(''); } }; return ( <div className="App"> <div className="chat-container"> <h2>Chat Room</h2> <div className="user-list"> <h3>Connected Users</h3> <ul> {users.map((user, idx) => ( <li key={idx}>{user}</li> ))} </ul> </div> <div className="chat-box"> {chat.map((message, index) => ( <div key={index} className="message"> <strong>{message.user}: </strong> {message.text} </div> ))} </div> <form onSubmit={sendMessage}> <input type="text" value={message} onChange={(e) => setMessage(e.target.value)} placeholder="Type a message" required /> <button type="submit">Send</button> </form> </div> </div> ); } export default App;
Step 4: Add CSS for styling
Create a new CSS file named App.css
in the src
directory and add the following styles:
body { font-family: 'Arial', sans-serif; background-color: #f5f5f5; margin: 0; padding: 20px; } .App { display: flex; justify-content: center; align-items: center; flex-direction: column; max-width: 800px; margin: auto; } .chat-container { width: 100%; padding: 20px; background: white; border-radius: 8px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); } h2 { text-align: center; } .user-list { margin-bottom: 10px; } .user-list ul { list-style-type: none; padding: 0; margin: 0; } .chat-box { height: 300px; overflow-y: auto; border: 1px solid #ddd; border-radius: 5px; padding: 10px; background-color: #fafafa; margin-bottom: 10px; } .message { margin-bottom: 10px; padding: 5px; border-radius: 5px; } .message strong { color: #007BFF; /* Username color */ } input[type="text"] { flex: 1; padding: 10px; border: 1px solid #ddd; border-radius: 5px; } button { padding: 10px 15px; background-color: #007BFF; color: white; border: none; border-radius: 5px; cursor: pointer; } button:hover { background-color: #0056b3; }
Testing the Application
Step 1: Run the backend server
In the terminal, navigate to your project directory and start the server:
node server.js
Step 2: Start the React app
In another terminal, navigate to the client
directory and run:
npm start
Result
Once everything is set up and running, you should be able to open your browser and navigate to http://localhost:3000
. You’ll see the chat interface, where you can type messages and see who is online.
Conclusion
In this blog post, we created a simple real-time chat application using Node.js and React. We covered setting up the server, managing socket connections, and creating the chat interface. This basic structure can be expanded with more features like user authentication, private messaging, and persistent chat history.
Feel free to experiment and enhance this application further! Happy coding!