# Building a Real-Time Chat App with Next.js and Socket.io (App Router)

Real-time applications, such as chat apps, require instant data exchange between clients and servers. In this guide, we'll walk through integrating [Socket.io](https://socket.io/docs/v4/tutorial/introduction) with [**Next.js (App Router)**](https://nextjs.org/docs/app/getting-started/installation) to build a real-time chat application.

---

## 🚀 Why Use Socket.io with Next.js?

**Socket.io** is a powerful WebSocket library that enables bi-directional communication between the client and server. Next.js **App Router (**`app/`**)** does not support API routes, so we need a separate WebSocket server.

### **Key Benefits:**

* **Low Latency:** Instant message delivery between users.
    
* **Separate WebSocket Server:** Enhances scalability and flexibility.
    
* **Works with App Router:** Since API routes are not available in `app/`, using a dedicated WebSocket server is ideal.
    

---

## 🛠️ Setting Up the Project

### **Step 1: Create a Next.js App**

Run the following command to set up a Next.js project:

```typescript
npx create-next-app@latest nextjs-chat-app --typescript
cd nextjs-chat-app
```

### **Step 2: Install Dependencies**

You'll need `socket.io` for both the server and client:

```typescript
npm install socket.io socket.io-client
```

---

## 🔧 Backend: Creating a WebSocket Server

Since API routes are not available in App Router, we must run a separate WebSocket server.

### **Step 3: Create** `server.ts`

📌 **Create a** `server.ts` **file in the root directory:**

```typescript
import { createServer } from 'http';
import { Server as SocketServer } from 'socket.io';

const httpServer = createServer();
const io = new SocketServer(httpServer, {
  cors: { origin: '*' },
});

io.on('connection', (socket) => {
  console.log('User connected:', socket.id);

  socket.on('message', (msg) => {
    console.log('Received message:', msg);
    io.emit('message', msg);
  });

  socket.on('disconnect', () => {
    console.log('User disconnected:', socket.id);
  });
});

// Start WebSocket server on port 3001
httpServer.listen(3001, () => {
  console.log('WebSocket server running on port 3001');
});
```

This server listens for WebSocket connections and handles real-time messaging.

---

## 🖥️ Frontend: Connecting to the WebSocket Server

### **Step 4: Create a Chat Component**

📌 **Create** `Chat.tsx` **in** `app/components/Chat.tsx`**:**

```typescript
'use client';

import { useEffect, useState } from 'react';
import { io, Socket } from 'socket.io-client';

let socket: Socket;

export default function Chat() {
  const [message, setMessage] = useState('');
  const [messages, setMessages] = useState<string[]>([]);

  useEffect(() => {
    socket = io('http://localhost:3001'); // Connect to WebSocket server

    socket.on('connect', () => {
      console.log('Connected:', socket.id);
    });

    socket.on('message', (msg) => {
      setMessages((prev) => [...prev, msg]);
    });

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

  const sendMessage = () => {
    if (socket && message.trim()) {
      socket.emit('message', message);
      setMessage('');
    }
  };

  return (
    <div>
      <h2>Real-Time Chat</h2>
      <div>
        {messages.map((msg, index) => (
          <p key={index}>{msg}</p>
        ))}
      </div>
      <input
        type="text"
        value={message}
        onChange={(e) => setMessage(e.target.value)}
      />
      <button onClick={sendMessage}>Send</button>
    </div>
  );
}
```

This component connects to the WebSocket server, listens for messages, and allows users to send chat messages.

---

## 📄 Step 5: Add Chat Component to a Page

📌 **Modify** `app/page.tsx` **to include the chat:**

```typescript
import Chat from './components/Chat';

export default function Home() {
  return (
    <div>
      <h1>Next.js Real-Time Chat App</h1>
      <Chat />
    </div>
  );
}
```

---

## 🔄 How Users Exchange Messages

Users will exchange messages in real-time through WebSockets. Here’s how it works:

1. **Client connects to the WebSocket server**:
    
    * The `Chat.tsx` component initializes a connection to the WebSocket server running on `http://localhost:3001`.
        
2. **Sending messages**:
    
    * When a user types a message and clicks "Send," the message is emitted using `socket.emit('message', message)`.
        
    * The server receives this message via the `socket.on('message', (msg) => { ... })` listener.
        
3. **Broadcasting messages**:
    
    * The server listens for incoming messages and then emits the message to **all connected clients** using `io.emit('message', msg)`.
        
    * This ensures that every client (including the sender) receives the message in real time.
        
4. **Receiving messages on the client**:
    
    * Every connected client listens for new messages with `socket.on('message', (msg) => { setMessages([...prevMessages, msg]) })`.
        
    * This updates the UI instantly with the received message.
        

By following this mechanism, multiple users can exchange messages in real time seamlessly.

---

## 🚀 Running the Chat App

### **Step 6: Start the WebSocket Server**

Before running your Next.js app, start the WebSocket server:

```typescript
node server.ts
```

### **Step 7: Start Your Next.js App**

Run Next.js separately:

```typescript
npm run dev
```

Visit `http://localhost:3000`, open multiple browser tabs, and chat in real-time!

---

## 📌 Conclusion

By integrating **Socket.io** with **Next.js (App Router)**, you've built a fully functional real-time chat application. This guide covered:

* **Setting up a separate WebSocket server** for Next.js App Router.
    
* **Connecting the client** to the WebSocket server using Socket.io.
    
* **Implementing real-time messaging** in a React component.
    

### **Next Steps:**

✅ Add **User Authentication**: Secure messages for logged-in users. ✅ Store **Chat History**: Use Firebase, PostgreSQL, or MongoDB. ✅ Implement **Group Chats & Notifications**.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1738524572188/80e51318-f1b0-4a01-960e-7c157929640c.jpeg align="center")
