Real-time Chat application under 5 minutes using NEXTJS and Socket.io
Tags: socketio, chatapplication, nextjs, realtimechatapp
Published: 2024-01-05 16:16:10

---
title: Real-time Chat application under 5 minutes using NEXTJS and Socket.io
published: true
date: 2023-01-06 13:05:28 UTC
tags: socketio,chatapplication,nextjs,realtimechatapp
canonical_url: 
---

## Real-time Chat application under 5 minutes using NEXTJS and Socket.io


### Let’s start the timer,

#### 1. First, create a next app

```
npx create-next-app@latest
```

After creating the Next app, our project structure looks something like this.

![](https://cdn-images-1.medium.com/max/362/1*oXeNwN8LokTFe19nrn19sw.png)
_Project structure_

#### 2. Install the following dependencies

```
npm i socket.io socket.io-client
```

![](https://cdn-images-1.medium.com/max/355/1*boWds86lG6eNAa77ZbNmVQ.png)
_Dependencies_

#### 3. Now let's start to code,

go to **_pages/index.js_** file and copy the basic template.

```
import React, { useEffect, useState } from "react";
import io from "socket.io-client";

let socket;

const Home = () => {
  useEffect(() => {
    socketInitializer();

    return () => {
      socket.disconnect();
    };
  }, []);

  async function socketInitializer() {
  }

  function handleSubmit(e) {
  }

  return (
    <div>
      <h1>Chat app</h1>
    </div>
  );
};

export default Home;
```

Whenever the component is mounted, **socketInitializer()** function is called and whenever the component is unmounted, we are disconnecting the socket connection. But where is the socket connection happening?

Before that let's set up the backend, here we use Nextjs which **allows you to create APIs endpoints in a pages directory as though you’re writing backend code**.

In **pages/api** we will create a new file called **socket.js.**

![](https://cdn-images-1.medium.com/max/356/1*LFiIDnYSqWsM340yujFxSg.png)
_pages/api/socket.js_

```
import { Server } from "socket.io";

export default function SocketHandler(req, res) {
  const io = new Server(res.socket.server);
  res.socket.server.io = io;

  io.on("connection", (socket) => {
    // after the connection.....
  });

  console.log("Setting up socket");
}
```

Now, when the client connects from the front end, the backend captures the connection even, with that we are creating a new socket.io server and assigning it to **_res.socket.server.io._**

```
// Waits for a socket connection
io.on("connection", socket => {
  // Each socket has a unique ID
  // console.log(socket.id) -> ojIckSD2jqNzOqIrAGzL
}) 
```

Improving the code.

```
import { Server } from "socket.io";

export default function SocketHandler(req, res) {
  if (res.socket.server.io) {
    console.log("Already set up");
    res.end();
    return;
  }

  const io = new Server(res.socket.server);
  res.socket.server.io = io;

  io.on("connection", (socket) => {
    socket.on("send-message", (obj) => {
      io.emit("receive-message", obj);
    });
  });

  console.log("Setting up socket");
  res.end();
}
```

Now here, if a **res.socket.server.io** exist, then no need to create the socket.io server again, so we are simpling returning **.**

Inside the socket connection, we have created a **listening event.**

So what it does is, Adds the _listener_ function to the end of the listener's array for the event named _send-message (we call it as emit)_. So whenever a emit happens from the frontend with the event named _send-message,_ then this event gets executed.

Inside it, we have an emitter named _receive-message_, which will emit the received object (obj) to the client side.

#### Now back to the client side, let’s connect to the backend.

```
import React, { useEffect, useState } from "react";
import io from "socket.io-client";

let socket;

const Home = () => {

  useEffect(() => {
    socketInitializer();

    return () => {
      socket.disconnect();
    };
  }, []);

  async function socketInitializer() {
    await fetch("/api/socket");

    socket = io();

    socket.on("receive-message", (data) => {
      // we get the data here
    });
  }

  function handleSubmit(e) {
  }

  return (
    <div>
      <h1>Chat app</h1>
    </div>
  );
};

export default Home;
```

We have initialized the socket by using the **fetch()**. This will create the socket server.

Next, we have an event listener which will listen if any emit is happening in the name **_receive-message._**

#### Let's create a simple UI

```
import React, { useEffect, useState } from "react";
import io from "socket.io-client";

let socket;

const Home = () => {
  const [message, setMessage] = useState("");
  const [username, setUsername] = useState("");

  useEffect(() => {
    socketInitializer();

    return () => {
      socket.disconnect();
    };
  }, []);

  async function socketInitializer() {
    await fetch("/api/socket");

    socket = io();

    socket.on("receive-message", (data) => {
      //
    });
  }

  function handleSubmit(e) {
  }

  return (
    <div>
      <h1>Chat app</h1>
      <h1>Enter a username</h1>

      <input value={username} onChange={(e) => setUsername(e.target.value)} />

      <br />
      <br />

      <div>
        <form onSubmit={handleSubmit}>
          <input
            name="message"
            placeholder="enter your message"
            value={message}
            onChange={(e) => setMessage(e.target.value)}
            autoComplete={"off"}
          />
        </form>
      </div>
    </div>
  );
};

export default Home;
```

![](https://cdn-images-1.medium.com/max/513/1*pclowDAQMctvsPQcoBMs5w.png)
_Simple UI_

Username and a message box, the message box input field is wrapped inside the form. Whenever the form is submitted, we are calling the **_handleSubmit_** function.

#### Now let’s emit the message

```
import React, { useEffect, useState } from "react";
import io from "socket.io-client";

let socket;

const Home = () => {
  const [message, setMessage] = useState("");
  const [username, setUsername] = useState("");
  const [allMessages, setAllMessages] = useState([]);

  useEffect(() => {
    socketInitializer();

    return () => {
      socket.disconnect();
    };
  }, []);

  async function socketInitializer() {
    await fetch("/api/socket");

    socket = io();

    socket.on("receive-message", (data) => {
      setAllMessages((pre) => [...pre, data]);
    });
  }

  function handleSubmit(e) {
    e.preventDefault();

    console.log("emitted");

    socket.emit("send-message", {
      username,
      message
    });

    setMessage("");
  }

  return (
    <div>
      <h1>Chat app</h1>
      <h1>Enter a username</h1>

      <input value={username} onChange={(e) => setUsername(e.target.value)} />

      <br />
      <br />

      <div>
        {allMessages.map(({ username, message }, index) => (
          <div key={index}>
            {username}: {message}
          </div>
        ))}

        <br />

        <form onSubmit={handleSubmit}>
          <input
            name="message"
            placeholder="enter your message"
            value={message}
            onChange={(e) => setMessage(e.target.value)}
            autoComplete={"off"}
          />
        </form>
      </div>
    </div>
  );
};

export default Home;
```

Inside the **_handleSubmit_** function, we have an emitter, that will emit a username and a message as an object to the _send-message_ event listener in the backend. After it reaches the backend, we have another emitter inside the event listener (_receive-message_), which will emit back to the frontend.

Now the receive-message event listener gets the data.

```
socket.on("receive-message", (data) => {
    setAllMessages((pre) => [...pre, data]);
});
```

All the above function happens Real-time to all the user’s currently using the application.

Go and play around with the code. Try creating a room for the user, refer to this [doc](https://socket.io/docs/v4/rooms/).

All the codes are the in my GitHub. Check them out and STAR the repository if you have successfully completed the Chat Application.

[GitHub - SarathAdhi/socket.io-starter-template: Created with CodeSandbox](https://github.com/SarathAdhi/socket.io-starter-template)

Like and wait for an awesome project with socket.io and Nextjs.

Spoiler alert, the next app would be a game.