Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I make socket.io work through proxy with react and vite using express backend?

I'm unable to get socket.io to work through proxy with react+vite (PORT 5173), express (PORT 5002). I'm receiving an ERROR: server error from my current configuration. And my backend isn't receiving any connection attempts.

I want the proxy to make the socket connection using my backend. (I think I'm trying to proxy the namespace e.g. const socket = io("/api"), to change from /api to http://localhost:5002))

Here are the relevant bits from my setup. My react / client component:

import { io } from 'socket.io-client';

export const socket = io('/ws', {
  autoConnect: false,
  withCredentials: true,
});

My vite.config.ts code:

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

// https://vitejs.dev/config/
export default defineConfig({
  server: {
    host: '0.0.0.0',
    proxy: {
      '/ws': {
        target: 'http://localhost:5002',
        changeOrigin: true,
        secure: false,
        ws: true,
        rewrite: path => path.replace(/^\/ws/, ''),
      },
    }
  },
  plugins: [react()],
});

My express server side code:

import express, from 'express';
import { createServer } from 'http';
import { Server } from 'socket.io';

const app = express();
const httpServer = createServer(app);

app.use(
  cors({
    credentials: true,
    origin: process.env.CLIENT_URL,
  })
);

const port = 5002;

const io = new Server(httpServer, {
   cors: {
     origin: process.env.CLIENT_URL,
     credentials: true,
   },
});

io.on('connection', async (socket) => {...})

httpServer.listen(port, () => {
  console.log(`Server is listening on Port: ${port}`);
});

Whenever I change the path in the vite config and react component from 'ws' to 'socket', the error changes and I get an Error: xhr poll error. When this happens my backend receives a GET /.io/?EIO=4&transport=polling&t=OXLHE7k 404 1.653 ms - 5

When I remove the proxy from vite and just use the complete url in the react component it works fine and everything functions as expected with no errors,

export const socket = io('http://localhost:5002', {
  autoConnect: false,
  withCredentials: true,
});

However I want to use the proxy now in dev, that's my goal and eventually I will use an nginx proxy in production.

like image 221
Findingoak2 Avatar asked Mar 25 '26 15:03

Findingoak2


1 Answers

The solution was to just use const socket = io(options) https://socket.io/docs/v4/client-initialization/#from-the-same-domain

Then the vite config would be:

export default defineConfig({
  server: {
    host: '0.0.0.0',
    proxy: {
      '/socket.io/': {
        target: 'http://localhost:5002',
        changeOrigin: true,
        secure: false,
        ws: true,
      },
    }
  },
  plugins: [react()],
});
like image 61
Findingoak2 Avatar answered Mar 28 '26 07:03

Findingoak2