Building a Real Time Chat Application with Next.js and Socket.IO

Building a Real Time Chat Application with Next.js and Socket.IO

Total Views - 72
   ||   Total likes - 3
By Jitender   ||    21 October 2024   ||     11 min read

In this tutorial, we will walk through the steps of creating a real-time chat application using Next.js and Socket.IO. We willl cover how to set up a Socket.IO server, create a Next.js application, connect to the server, join chat rooms, create a Docker file, and deploy the application on Hugging Face.

Table of Contents

1. Setting Up the Socket.IO Server

2. Creating a web application

3. Connecting to the Socket.IO Server

4. Joining a Chat Room

5. Creating a Docker File

6. Deploying on Hugging Face

If you face any issue watch this video

Step 1. Visit https://huggingface.co/

Step 2. Verify youself on huggingface

Step 3. Navigate to the spaces tab in the nav bar

Step 4. Click on create new space

Step 5. Now on this page type space name

Step 6. Select the Space SDK as "Docker"

Step 7. Choose a Docker template as "Blank"

Step 8. Click on create space button

Now clone the repo link to the local system

move inside the folder by

Copy ❐
1cd chat-server

Next, initialize a new Node.js project:

Copy ❐
1npm init -y

Install the required packages:

Copy ❐
1npm install express socket.io cors

Now, create a file named server.js and add the following code:

Copy ❐
1const express = require('express')
2const http = require('http');
3const socketio = require('socket.io');
4const cors = require('cors');
5const app = express();
6const server = http.createServer(app);
7const io = socketio(server,{
8 cors:{
9 origin:"*",
10 methods:['GET','POST'],
11 }
12})
13app.use(cors());
14io.on('connection', (socket) => {
15 socket.on('JoinWeChatRoom', (roomId) => {
16 socket.join(roomId);
17 });
18 socket.on('SendMessage',(message)=>{
19 const {roomId} = message;
20 io.to(roomId).emit('receiveMessage', message);
21 })
22 socket.on('disconnect',()=>{
23 })
24});
25server.listen(7860,()=>{
26 console.log('server is running at port 7860');
27})
28

To start the server, run:

Copy ❐
1node server.js

Now move to browser and type localhost:7860

You should get a message as "Server is running on 7860"

Now start building our frontend

Now integrate backend with frontend

Create a file with the name index.html and paste this code

Copy ❐
1<!DOCTYPE html>
2<html lang="en">
3
4<head>
5 <meta charset="UTF-8">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0">
7 <title>We Chat: Empowered by I Plus T Solutions</title>
8 <meta name="description" content="A cutting-edge communication platform designed to facilitate seamless interactions and foster meaningful connections." />
9 <link rel="icon" type="image/png" href="https://www.iplust.in/icon.png" />
10 <style>
11 /* page.module.css */
12 * {
13 margin: 0;
14 padding: 0;
15 box-sizing: border-box;
16 scrollbar-width: 0;
17 }
18
19 .container {
20 display: flex;
21 flex-direction: column;
22 align-items: center;
23 justify-content: center;
24 min-height: 100dvh;
25 background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
26 font-family: 'Poppins', sans-serif;
27 }
28
29 .title {
30 font-size: 4rem;
31 color: #fff;
32 margin-bottom: 2rem;
33 text-shadow: 2px 2px 8px rgba(0, 0, 0, 0.3);
34 }
35
36 .form {
37 display: flex;
38 flex-direction: column;
39 align-items: center;
40 background: rgba(255, 255, 255, 0.2);
41 padding: 2rem;
42 border-radius: 15px;
43 box-shadow: 0 8px 30px rgba(0, 0, 0, 0.1);
44 backdrop-filter: blur(10px);
45 }
46
47 .input {
48 width: 300px;
49 padding: 1rem;
50 font-size: 1.2rem;
51 border: none;
52 border-radius: 8px;
53 margin-bottom: 1.5rem;
54 background: rgba(255, 255, 255, 0.8);
55 color: #333;
56 box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.1);
57 transition: all 0.3s ease;
58 }
59
60 .input:focus {
61 outline: none;
62 box-shadow: 0 0 10px rgba(255, 255, 255, 0.6), 0 4px 8px rgba(0, 0, 0, 0.2);
63 }
64
65 .button {
66 padding: 0.8rem 2rem;
67 font-size: 1.2rem;
68 font-weight: bold;
69 color: #fff;
70 background: linear-gradient(135deg, #ff512f, #f09819);
71 border: none;
72 border-radius: 8px;
73 cursor: pointer;
74 transition: transform 0.3s ease, box-shadow 0.3s ease;
75 box-shadow: 0 8px 15px rgba(255, 81, 47, 0.3);
76 }
77
78 .button:hover {
79 transform: translateY(-4px);
80 box-shadow: 0 10px 20px rgba(255, 81, 47, 0.4);
81 }
82
83 .button:active {
84 transform: translateY(0);
85 box-shadow: 0 5px 10px rgba(255, 81, 47, 0.2);
86 }
87
88 @media (max-width: 768px) {
89 .input {
90 width: 80%;
91 }
92
93 .title {
94 font-size: 2rem;
95 }
96 }
97 </style>
98</head>
99
100<body>
101 <div class="container">
102 <h1 class="title">Join a Room</h1>
103 <form class="form" id="joinForm">
104 <input type="text" placeholder="Your Name" id="nameInput" class="input" required />
105 <input type="text" placeholder="Room ID" id="roomIdInput" class="input" required />
106 <button type="submit" class="button">Join Room</button>
107 </form>
108 </div>
109
110 <script>
111 const urlParams = new URLSearchParams(window.location.search);
112 const roomId = urlParams.get('roomId') || '';
113 document.getElementById('roomIdInput').value = roomId;
114 document.getElementById('joinForm').addEventListener('submit', function (e) {
115 e.preventDefault();
116 const name = document.getElementById('nameInput').value.trim();
117 const roomId = document.getElementById('roomIdInput').value.trim();
118 if (roomId && name) {
119 // Redirect to the join room URL with the room ID and name
120 const cleanRoomId = roomId.split(" ").join('');
121 window.location.href = `/join?roomId=${cleanRoomId}&name=${name}`;
122 }
123 });
124 </script>
125</body>
126
127</html>

with this code we can get name and room Id

Now create a file with the name chat.html and paste this code

Copy ❐
1<!DOCTYPE html>
2<html lang="en">
3
4<head>
5 <meta charset="UTF-8">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0">
7 <title>We Chat: Empowered by I Plus T Solutions</title>
8 <meta name="description" content="A cutting-edge communication platform designed to facilitate seamless interactions and foster meaningful connections." />
9 <link rel="icon" type="image/png" href="https://www.iplust.in/icon.png" />
10 <script src="https://cdn.socket.io/4.0.0/socket.io.min.js"></script>
11 <style>
12 /* chat.module.css */
13 * {
14 margin: 0;
15 padding: 0;
16 box-sizing: border-box;
17 scrollbar-width: 0;
18 }
19
20 /* For WebKit browsers (Chrome, Safari) */
21 *::-webkit-scrollbar {
22 display: none;
23 /* Hides the scrollbar */
24 }
25
26 .container {
27 display: flex;
28 flex-direction: column;
29 justify-content: space-between;
30 width: 100vw;
31 height: 100dvh;
32 padding: 20px;
33 background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
34 font-family: 'Poppins', sans-serif;
35 box-shadow: 0 8px 30px rgba(0, 0, 0, 0.2);
36 }
37
38 .header {
39 display: flex;
40 justify-content: space-between;
41 align-items: center;
42 margin-bottom: 20px;
43 }
44
45 .roomTitle {
46 color: white;
47 font-size: 1.5rem;
48 margin: 0;
49 text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.2);
50 }
51
52 .copyButton {
53 padding: 0.5rem 1rem;
54 font-size: 1rem;
55 color: white;
56 background-color: #ff512f;
57 border: none;
58 border-radius: 8px;
59 cursor: pointer;
60 transition: background 0.3s ease;
61 box-shadow: 0 4px 10px rgba(255, 81, 47, 0.3);
62 }
63
64 .copyButton:hover {
65 background-color: #f09819;
66 }
67
68 .chatBox {
69 flex: 1;
70 /* This makes the chatbox grow to fill the space */
71 overflow-y: auto;
72 background-color: rgba(255, 255, 255, 0.1);
73 padding: 20px;
74 border-radius: 10px;
75 box-shadow: inset 0 4px 8px rgba(0, 0, 0, 0.2);
76 backdrop-filter: blur(10px);
77 }
78
79 .senderMessage,
80 .receiverMessage {
81 padding: 10px 15px;
82 border-radius: 10px;
83 font-size: 1rem;
84 width: fit-content;
85 line-height: 1.4;
86 box-shadow: 0 3px 8px rgba(0, 0, 0, 0.1);
87 }
88
89 .chatBoxInputleft {
90 width: 100%;
91 display: flex;
92 justify-content: end;
93 margin-bottom: 15px;
94 }
95
96 .chatBoxInputright {
97 width: 100%;
98 margin-bottom: 15px;
99 display: flex;
100 justify-content: flex-start;
101 }
102
103 .senderMessage {
104 background: linear-gradient(135deg, #ff512f, #f09819);
105 color: white;
106 min-width: 40px;
107 text-align: end;
108 }
109
110 .receiverMessage {
111 background: rgba(255, 255, 255, 0.8);
112 color: #333;
113 min-width: 40px;
114 }
115
116 .inputContainer {
117 display: flex;
118 gap: 10px;
119 margin-top: 20px;
120 }
121
122 .input {
123 flex: 1;
124 padding: 10px;
125 font-size: 1rem;
126 border-radius: 8px;
127 border: none;
128 box-shadow: inset 0 3px 6px rgba(0, 0, 0, 0.1);
129 }
130
131 .input:focus {
132 outline: none;
133 box-shadow: 0 0 8px rgba(255, 255, 255, 0.6);
134 }
135
136 .sendButton {
137 padding: 10px 20px;
138 font-size: 1rem;
139 font-weight: bold;
140 color: white;
141 background: linear-gradient(135deg, #667eea, #764ba2);
142 border: none;
143 border-radius: 8px;
144 cursor: pointer;
145 transition: background 0.3s ease, transform 0.3s ease;
146 box-shadow: 0 6px 12px rgba(118, 75, 162, 0.3);
147 }
148
149 .sendButton:hover {
150 background: linear-gradient(135deg, #546de5, #5f27cd);
151 transform: translateY(-2px);
152 }
153
154 .sendButton:active {
155 transform: translateY(0);
156 }
157
158 @media screen and (max-width: 600px) {
159 .container {
160 padding: 5px;
161 }
162
163 .chatBox {
164 padding: 10px;
165 }
166
167 .senderMessage {
168 padding: 5px;
169 border-radius: 5px;
170 }
171
172 .receiverMessage {
173 padding: 5px;
174 border-radius: 5px;
175 }
176 }
177 </style>
178</head>
179
180<body>
181 <div class="container">
182 <div class="header">
183 <h2 class="roomTitle" id="roomTitle">Room: </h2>
184 <button onclick="copyRoomId()" class="copyButton">Invite Others to JOIN</button>
185 </div>
186 <div id="chatBox" class="chatBox"></div>
187 <form id="messageForm" class="inputContainer">
188 <input type="text" id="messageInput" placeholder="Type a message..." class="input" required />
189 <button type="submit" class="sendButton">Send</button>
190 </form>
191 </div>
192
193 <script>
194 const chatBox = document.getElementById('chatBox');
195 const messageForm = document.getElementById('messageForm');
196 const messageInput = document.getElementById('messageInput');
197 const roomTitle = document.getElementById('roomTitle');
198
199 const socket = io(window.location.origin);
200 const urlParams = new URLSearchParams(window.location.search);
201 const roomId = urlParams.get('roomId') || 'defaultRoom';
202 const name = urlParams.get('name') || 'Anonymous';
203
204 roomTitle.textContent = 'Room: ' + roomId;
205
206 socket.emit('JoinWeChatRoom', roomId);
207
208 socket.on('receiveMessage', (message) => {
209 const messageDiv = document.createElement('div');
210 messageDiv.className = message.sender === name ? 'chatBoxInputleft' : 'chatBoxInputright';
211 const messageContent = document.createElement('div');
212 messageContent.className = message.sender === name ? 'senderMessage' : 'receiverMessage';
213 messageContent.textContent = message.text;
214 messageDiv.appendChild(messageContent);
215 chatBox.appendChild(messageDiv);
216 chatBox.scrollTop = chatBox.scrollHeight;
217 });
218
219 messageForm.addEventListener('submit', function (e) {
220 e.preventDefault();
221 const newMessage = messageInput.value.trim();
222 if (newMessage) {
223 const messageData = { roomId, text: newMessage, sender: name };
224 socket.emit('SendMessage', messageData);
225 messageInput.value = '';
226 }
227 });
228
229 function copyRoomId() {
230 navigator.clipboard.writeText(window.location.origin + `?roomId=${roomId}`);
231 alert('Link copied!');
232 }
233 </script>
234</body>
235
236</html>

with this you will be able to create a connection and can chat to each other

Now create a file with the name "Dockerfile" and paste this code

Copy ❐
1# Use the official Node.js image from Docker Hub
2FROM node:16-alpine
3
4# Create a non-root user
5RUN adduser -D user
6USER user
7
8# Set the working directory
9WORKDIR /app
10
11# Copy package.json and package-lock.json to install dependencies
12COPY --chown=user:user ./package*.json ./
13
14# Install dependencies
15RUN npm install
16
17# Copy the entire project
18COPY --chown=user:user . .
19
20# Expose the port (Hugging Face Spaces expects your app to run on port 7860)
21EXPOSE 7860
22
23# Start the application
24CMD ["npm", "start"]

Now register the routes to the server, for this move to the server.js file and update the code

Copy ❐
1const express = require('express')
2const http = require('http');
3const socketio = require('socket.io');
4const cors = require('cors');
5const app = express();
6const server = http.createServer(app);
7const io = socketio(server,{
8 cors:{
9 origin:"*",
10 methods:['GET','POST'],
11 }
12})
13app.use(cors());
14app.get('/', (req, res) => {
15 res.sendFile(__dirname + `/index.html`);
16});
17app.get('/join/', (req, res) => {
18 res.sendFile(__dirname + `/chat.html`);
19});
20io.on('connection', (socket) => {
21 socket.on('JoinWeChatRoom', (roomId) => {
22 socket.join(roomId);
23 });
24 socket.on('SendMessage',(message)=>{
25 const {roomId} = message;
26 io.to(roomId).emit('receiveMessage', message);
27 })
28 socket.on('disconnect',()=>{
29 })
30});
31server.listen(7860,()=>{
32 console.log('server is running at port 7860');
33})
34

Now edit package.json file

Add a line to your script and change main key

Copy ❐
1"start":"node server.js",
Copy ❐
1"main": "server.js",

Now again restart the server

Copy ❐
1npm start

Now again move to browser and type localhost:7860

Now start testing your application

If every thing works fine we will deploy it to hugging-face, if you face any error watch full video again

Now open your terminal and follow these three commands

Copy ❐
1git add .
Copy ❐
1git commit -m "Chat Bot"
Copy ❐
1git push

Now at this time you might get a prompt to verify yourself provide your username and password

now your bot is deployed go to hugging face

Note: If you need your project URL then watch full video in the top

Congratulations! You’ve successfully built a real-time chat application using Socket.IO, containerized it with Docker, and deployed it on Hugging Face. You can extend this application by adding more features, such as user authentication, chat history, and styling with CSS frameworks.

Feel free to explore and enhance your chat application. Happy coding!

Follow US

Thank You

Comments Of This Blog ...

Top Results
Tags
Ads
banner