Next.js Discord

Discord Forum

Socket.IO and NextJS

Unanswered
Hackberry nipple gall parasitoid posted this in #help-forum
Open in Discord
Hackberry nipple gall parasitoidOP
I have made a coinflip game, which has 3 states, Creation, Join & Update, where the page where they are located at it should refresh that part of the components, and I thought of using Socket.IO for realtime update, but... I'm using NextJS 15 with the new Route System and I have absolutely no idea how to structure the socket and the web app, as I never done it before, if someone could explain how to do it, I would love to learn how to do it

58 Replies

@Hackberry nipple gall parasitoid I have made a coinflip game, which has 3 states, Creation, Join & Update, where the page where they are located at it should refresh that part of the components, and I thought of using Socket.IO for realtime update, but... I'm using NextJS 15 with the new Route System and I have absolutely no idea how to structure the socket and the web app, as I never done it before, if someone could explain how to do it, I would love to learn how to do it
If you are going to host nextjs on services like vercel/netlify or similar, you cannot run a socket server in route handlers. You will need to either host a dedicated socket server in a serverful environment or just services like ably/pusher.

and you can just use the same code structure you used to do earlier in pages router, just make sure its a client component
Hackberry nipple gall parasitoidOP
yeah no
I have no idea what to do lol
Transvaal lion
- Host a dedicated websocket server, either standalone or using an Express / Hono / etc. server
- In your Next.js app, create a WebsocketProvider to wrap your entire app and make the Socket.io client available.

// WebsocketProvider.tsx

"use client"
export const socket = io(/* WS URL */, {
    transports: ["websocket", "polling"],
    withCredentials: true,
    autoConnect: false, // important!
    reconnection: true,
    reconnectionAttempts: 10,
    reconnectionDelay: 1000,
})

export const WebsocketProvider = ({ children }: { children: ReactNode }) => {
    useEffect(() => {
        socket.connect()

        // Add your global listeners here
        socket.on("connect", () => console.log("client connected"))

        return () => {
            socket.off("connect")
            socket.close()
        }
    }, [])

    return children
}


In your root layout, wrap your app with that:
const RootLayout = ({ children }: { children: React.ReactNode }) => {
    return (
        <html>
            <head></head>
            <body>
                <WebsocketProvider>
                    {children}
                </WebsocketProvider>
            </body>
        </html>
    )
}

export default RootLayout


You can also register additional events in components by using the socket in a useEffect.
// in any child component
useEffect(() => {
    socket.on("coinflip-start", (id) => {
      if (id == thisCoinflipGame.id) doWhatever()
    })

    return () => {
        socket.off("coinflip-start")
    }
}, [])
and uses socket.io?
oh I need to host it in locale for testing right?
Transvaal lion
It's not that complex, but I assume you're a beginner based off of your messages.
You can host Nextjs on Vercel for free. https://vercel.com/home
But for the websocket server you probably need a VPS. There are options starting from 5€ at DigitalOcean or Hetzner.

Obviously, for development you don't need a VPS and you can run the Socket.io server and Nextjs locally.
If you don't know how to set any of this up locally, I highly suggest following some tutorials or reading through the docs step by step, especially if you've never worked with these tools before.
Transvaal lion
No, it does work with Next 15 and the app router
@Transvaal lion No, it does work with Next 15 and the app router
Hackberry nipple gall parasitoidOP
so i can use what you have suggested?
Transvaal lion
Yes
@Transvaal lion No, it does work with Next 15 and the app router
Hackberry nipple gall parasitoidOP
it is correct?
damn
docs sucks
@Hackberry nipple gall parasitoid it is correct?
Transvaal lion
You'll have to try. I never use a custom Nextjs server
@Transvaal lion You'll have to try. I never use a custom Nextjs server
Hackberry nipple gall parasitoidOP
how you have done it..?
cuz I have no idea what I'm doing as socket.io suggest like this and says that I will not be able to use the free vercel host
hmm
Transvaal lion
Correct. A custom Nextjs server can not be deployed to Vercel.

You need to create a separate project for the websocket server. E.g. your Next app then runs on port 3000 and your websocket server on port 3100 or whatever you choose.

https://socket.io/docs/v4/server-initialization/
and it works, for now
oh and
im using webp is that a problem .. ?
not sure where do i get this error from as I cannot understand the origin and many find other things which I cannot find lol
Transvaal lion
I'm not familiar with that error. Try googling or searching this Discord for answers
@Transvaal lion I'm not familiar with that error. Try googling or searching this Discord for answers
Hackberry nipple gall parasitoidOP
oh okay, back to socket.io it saying that socket.emit its not a function what that means?
Error creating game: TypeError: _components_WebsocketProvider__WEBPACK_IMPORTED_MODULE_5__.socket.emit is 
not a function
    at createGame (webpack-internal:///(action-browser)/./src/server/game.ts:70:75)
socket.emit("game:join", JSON.stringify(updatedGame));
im sending data, which is
await prisma.game.update({});
I need to send data from the server to the client
yea idk
my websocket provider doesnt work ..
i cannot make the websocket provider work its doesnt connect no idea
im using discord outh something with that ...?
not idea
Hackberry nipple gall parasitoidOP
hello .. ?
nvm
it says connect
but nothing get passed
its should say things but it doesnt
... ?
"use client";

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

// Create socket outside but don't connect yet
export let socket: Socket | null = null;

export function getSocket() {
  if (!socket) {
    console.log("Creating new socket instance");
    socket = io("http://192.168.1.69:3000", {
      transports: ["websocket", "polling"],
      withCredentials: true,
      autoConnect: false,
      reconnection: true,
      reconnectionAttempts: 10,
      reconnectionDelay: 1000,
    });
  }
  return socket;
}

export const WebsocketProvider = ({ children }: { children: ReactNode }) => {
  const [isConnected, setIsConnected] = useState(false);
  const [connectionAttempted, setConnectionAttempted] = useState(false);

  useEffect(() => {
    console.log("WebsocketProvider mounting...");

    // Get socket instance
    const socket = getSocket();

    // Don't connect if we're already connected
    if (!socket.connected) {
      console.log("Attempting socket connection...");
      socket.connect();
      setConnectionAttempted(true);
    }

    const onConnect = () => {
      console.log("Socket connected:", socket.id);
      setIsConnected(true);
    };

    const onConnectError = (err: Error) => {
      console.error("Socket connection error:", err.message);
    };

    const onDisconnect = (reason: string) => {
      console.log("Socket disconnected:", reason);
      setIsConnected(false);
    };

    // Setup listeners
    socket.on("connect", onConnect);
    socket.on("connect_error", onConnectError);
    socket.on("disconnect", onDisconnect);

    // Cleanup on unmount
    return () => {
      console.log("WebsocketProvider unmounting...");
      socket.off("connect", onConnect);
      socket.off("connect_error", onConnectError);
      socket.off("disconnect", onDisconnect);
      // Don't close - might be in use elsewhere
    };
  }, []);

  // Visual indication for debugging
  return (
    <>
      {connectionAttempted && !isConnected && (
        <div
          style={{
            position: "fixed",
            bottom: 0,
            right: 0,
            background: "red",
            padding: "2px 5px",
            fontSize: "50px",
            zIndex: 9999,
          }}
        >
          Socket disconnected
        </div>
      )}
      {children}
    </>
  );
};

// Export a hook to use socket
export function useSocket() {
  return getSocket();
}
hmmmmmmmmmmmmmmmmmmmmm
i found the error
Hackberry nipple gall parasitoidOP
useEffect(() => {
    setInterval(() => {
      socket.on("game:created", (data) => {
        console.log("Game created:", data);
        setGames((prev) => [data, ...(prev || [])]);
      });
    }, 1000);
  }, []);
its that correct for polling?
and how to refresh only a part of the page?
not sure how to do so...
Hackberry nipple gall parasitoidOP
up