Custom socket.io server.ts in nextjs baby.

Create a server.ts file in root dir of your nextjs project. vim server.ts import { createServer } from 'http' import { parse } from 'url' import next from 'next' const port = parseInt(process.env.PORT || '3000', 10) const dev = process.env.NODE_ENV !== 'production' const app = next({ dev }) const handle = app.getRequestHandler() app.prepare().then(() => { const httpServer = createServer((req, res) => { const parsedUrl = parse(req.url!, true) handle(req, res, parsedUrl) }) httpServer.listen(port) console.log( `> Server listening at http://localhost:${port} as ${dev ? 'development' : process.env.NODE_ENV }` ) }) For socket.io. pnpm add socket.io socket.io-client vim server.ts #...imports import { Server } from "socket.io"; # const httpServer = ...} const io = new Server(httpServer, { // options }); # socket stuff io.on("connect", (socket) => { console.log("Socket connected", socket.id) socket.on("msg", (data) => { console.log(data) socket.emit("msg", data) }) }); # ...rest package.json pnpm add cross-env pnpm add ts-node -D "type": "module", "scripts": { "dev": "nodemon", "build": "next build && tsc --project tsconfig.server.json", "start": "cross-env NODE_ENV=production node dist/server.js" }, 4.tsconfig-server.json { "extends": "./tsconfig.json", "compilerOptions": { "module": "es2015", "outDir": "dist", "lib": ["es2019"], "target": "es2019", "isolatedModules": false, "noEmit": false }, "include": ["server.ts"] } app/page.tsx (whatever) "use client"; import { useEffect, useRef } from "react"; import { Button } from "@/components/ui/button"; import { io, Socket } from "socket.io-client"; export default function Home() { const socketRef = useRef(null); useEffect(() => { socketRef.current = io("ws://localhost:3000", { reconnectionDelayMax: 10000, }); // Cleanup the socket connection on unmount return () => { socketRef.current?.disconnect(); }; }, []); const handleSend = () => { socketRef.current?.emit("msg", { a: "b", c: [] }); socketRef.current?.on("msg", (data) => { console.log(data) }) }; return Send }

Feb 19, 2025 - 09:59
 0
Custom socket.io server.ts in nextjs baby.
  1. Create a server.ts file in root dir of your nextjs project. vim server.ts
import { createServer } from 'http'
import { parse } from 'url'
import next from 'next'

const port = parseInt(process.env.PORT || '3000', 10)
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()

app.prepare().then(() => {
  const httpServer = createServer((req, res) => {
    const parsedUrl = parse(req.url!, true)
    handle(req, res, parsedUrl)
  })
  httpServer.listen(port)
  console.log(
    `> Server listening at http://localhost:${port} as ${dev ? 'development' : process.env.NODE_ENV
    }`
  )
})
  1. For socket.io.

pnpm add socket.io socket.io-client
vim server.ts

#...imports
import { Server } from "socket.io";
# const httpServer = ...}
const io = new Server(httpServer, {
    // options
  });
# socket stuff
io.on("connect", (socket) => {
    console.log("Socket connected", socket.id)
    socket.on("msg", (data) => {
      console.log(data)
      socket.emit("msg", data)
    })
  });
# ...rest
  1. package.json

pnpm add cross-env
pnpm add ts-node -D

"type": "module",
"scripts": {
  "dev": "nodemon",
  "build": "next build && tsc --project tsconfig.server.json",
  "start": "cross-env NODE_ENV=production node dist/server.js"
},

4.tsconfig-server.json

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "module": "es2015",
    "outDir": "dist",
    "lib": ["es2019"],
    "target": "es2019",
    "isolatedModules": false,
    "noEmit": false
  },
  "include": ["server.ts"]
}
  1. app/page.tsx (whatever)
"use client";

import { useEffect, useRef } from "react";
import { Button } from "@/components/ui/button";
import { io, Socket } from "socket.io-client";

export default function Home() {
  const socketRef = useRef<Socket | null>(null);

  useEffect(() => {
    socketRef.current = io("ws://localhost:3000", {
      reconnectionDelayMax: 10000,
    });
    // Cleanup the socket connection on unmount
    return () => {
      socketRef.current?.disconnect();
    };
  }, []);

  const handleSend = () => {
    socketRef.current?.emit("msg", { a: "b", c: [] });
    socketRef.current?.on("msg", (data) => {
      console.log(data)
    })
  };

  return <Button onClick={handleSend}>SendButton>
}