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

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

Β·

4 min read

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 with Next.js (App Router) 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:

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:

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:

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:

'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:

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:

node server.ts

Step 7: Start Your Next.js App

Run Next.js separately:

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.

Β