Real-time communication has become an essential part of modern web applications. Whether it’s for customer support, team collaboration, or social interaction, real-time chat apps are everywhere. Next.js, combined with WebSockets, provides a powerful solution for building fast, scalable real-time chat applications.
In this blog post, we’ll walk through building a simple real-time chat application using Next.js and WebSockets. You’ll learn how to set up WebSocket communication, manage messages, and create a real-time chat UI with React.
What Are WebSockets?
Before we dive into the code, let's quickly go over WebSockets.
WebSockets provide full-duplex communication channels over a single TCP connection. Unlike traditional HTTP requests, WebSockets allow for continuous bi-directional communication between the client and the server. This makes WebSockets ideal for applications that require real-time data exchange, such as chat apps, live notifications, or collaborative apps.
Prerequisites
To follow along with this tutorial, you should have:
- Node.js installed on your system.
- A basic understanding of React and Next.js.
- Familiarity with WebSockets (though we'll explain the basics as we go).
- Socket.IO installed in your project (we’ll use this library to simplify WebSocket communication).
Step 1: Set Up Your Next.js Project
Start by creating a new Next.js project if you don’t have one already:
npx create-next-app real-time-chat
cd real-time-chat
Once the project is set up, install Socket.IO (we’ll use it both for the client and server sides):
npm install socket.io-client socket.io
Step 2: Set Up a WebSocket Server
Now, let’s set up a WebSocket server that will handle the real-time communication. In Next.js, we can use API Routes to create a server-side WebSocket connection.
- Inside the
pages/api
directory, create a new file calledchat.js
:
mkdir pages/api
touch pages/api/chat.js
- Open
chat.js
and add the following code:
// pages/api/chat.js
import { Server } from 'socket.io';
export default function handler(req, res) {
if (req.method === 'GET') {
res.status(200).json({ message: 'Chat API' });
} else {
res.status(405).send('Method Not Allowed');
}
}
export function configureSocket(server) {
const io = new Server(server, {
path: '/api/chat',
cors: {
origin: '*',
methods: ['GET', 'POST'],
},
});
io.on('connection', (socket) => {
console.log('A user connected');
// Listen for incoming messages
socket.on('send_message', (message) => {
io.emit('receive_message', message); // Emit message to all clients
});
socket.on('disconnect', () => {
console.log('A user disconnected');
});
});
}
Explanation:
-
Socket.IO Server: We use the
socket.io
library to create a WebSocket server that listens for incoming connections and messages. - CORS Configuration: To allow communication from different origins (client-server), we configure CORS to accept requests from any origin.
-
send_message
&receive_message
events: The server listens forsend_message
events and broadcasts the message to all connected clients using thereceive_message
event.
Next, we need to ensure that the WebSocket server is initialized when Next.js starts up. To do this, we will modify the next.config.js
file:
// next.config.js
module.exports = {
webpack: (config, { isServer }) => {
if (isServer) {
const { configureSocket } = require('./pages/api/chat');
const http = require('http');
const server = http.createServer(config.server);
configureSocket(server);
return config;
}
return config;
},
};
Step 3: Create the Frontend (React & Socket.IO Client)
Now, let’s set up the frontend that communicates with the WebSocket server. We’ll use Socket.IO Client on the frontend to establish a WebSocket connection.
In the
pages
directory, openindex.js
(or create a new component if you prefer).Add the following code to set up the chat UI and WebSocket client logic:
// pages/index.js
import { useState, useEffect, useRef } from 'react';
import io from 'socket.io-client';
export default function Home() {
const [messages, setMessages] = useState([]);
const [message, setMessage] = useState('');
const socketRef = useRef(null);
useEffect(() => {
// Initialize WebSocket connection
socketRef.current = io({
path: '/api/chat',
});
// Listen for incoming messages
socketRef.current.on('receive_message', (message) => {
setMessages((prevMessages) => [...prevMessages, message]);
});
return () => {
socketRef.current.disconnect();
};
}, []);
const sendMessage = () => {
if (message.trim()) {
socketRef.current.emit('send_message', message);
setMessage('');
}
};
return (
<div style={{ maxWidth: '600px', margin: '0 auto', padding: '2rem' }}>
<h1>Real-Time Chat</h1>
<div
style={{
height: '300px',
overflowY: 'scroll',
border: '1px solid #ddd',
padding: '1rem',
marginBottom: '1rem',
}}
>
{messages.map((msg, index) => (
<div key={index}>
<strong>User:</strong> {msg}
</div>
))}
</div>
<input
type="text"
placeholder="Type a message"
value={message}
onChange={(e) => setMessage(e.target.value)}
style={{ width: '100%', padding: '0.5rem' }}
/>
<button onClick={sendMessage} style={{ marginTop: '0.5rem', width: '100%' }}>
Send
</button>
</div>
);
}
Explanation:
-
Socket.IO Client: We use
socket.io-client
to establish a WebSocket connection to the server at/api/chat
. -
Messages: The
messages
state stores the list of chat messages. When a new message is received, we append it to the message list. - sendMessage: When the user sends a message, the message is emitted to the server, and once the server responds with the broadcasted message, the message is displayed in the UI.
- UI: A simple interface with an input field for typing messages and a button to send them.
Step 4: Running the Application
Now that everything is set up, run the application with:
npm run dev
Visit http://localhost:3000
in your browser. Open multiple tabs, and you should see that when you send a message in one tab, it immediately appears in the other tabs in real-time.
Conclusion
Congratulations! You’ve just built a simple real-time chat application using Next.js and WebSockets. By using Socket.IO, we’ve simplified the WebSocket integration for real-time bidirectional communication.
Key Takeaways:
- WebSockets enable real-time communication between the client and the server.
- Socket.IO simplifies WebSocket implementation, handling connection, reconnection, and message broadcasting.
- We used Next.js API Routes to set up the WebSocket server.
- The application updates in real-time as messages are sent and received.
You can now extend this app with features like:
- User authentication (using JWT or OAuth).
- Private messages or group chats.
- Message persistence with a database (e.g., MongoDB or Firebase).
Real-time chat is just one of the many powerful applications that WebSockets enable. With Next.js and WebSockets, you can create fast, scalable apps that deliver instant experiences to your users.
Happy coding!
Top comments (0)