From 8381270b6aa0af9e771b6331f74b819d1224b4b0 Mon Sep 17 00:00:00 2001 From: Jon Ayers Date: Mon, 17 Nov 2025 18:35:13 +0000 Subject: [PATCH 1/2] fix: allow *.coder domains in vite dev server Add .coder to allowedHosts for both dev server and preview mode to support Coder workspace access patterns. When MUX_VITE_HOST=0.0.0.0, allow all hosts. fix: replace 0.0.0.0 backend URL with client hostname When VITE_BACKEND_URL contains 0.0.0.0 (server bind address), replace it with window.location.hostname so WebSocket clients can actually connect. Fixes: WebSocket connection to 'ws://0.0.0.0:3000/ws' failed fix: update dev-server to watch correct output paths nodemon was watching dist/main.js but build outputs to dist/cli/index.js and dist/cli/server.js. Update both Windows and Unix dev-server targets. fix: use clientPort for Vite HMR when binding to 0.0.0.0 When MUX_VITE_HOST=0.0.0.0, use clientPort instead of explicit host to let the browser use its own hostname for HMR WebSocket connections. Fixes: WebSocket connection to 'ws://0.0.0.0:5173/?token=...' failed --- Makefile | 4 ++-- src/browser/api.ts | 13 +++++++++++-- vite.config.ts | 15 ++++++--------- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/Makefile b/Makefile index 23d219517..2ecfedee4 100644 --- a/Makefile +++ b/Makefile @@ -134,7 +134,7 @@ dev-server: node_modules/.installed build-main ## Start server mode with hot rel @# On Windows, use npm run because bunx doesn't correctly pass arguments @npmx concurrently -k \ "npmx nodemon --watch src --watch tsconfig.main.json --watch tsconfig.json --ext ts,tsx,json --ignore dist --ignore node_modules --exec node scripts/build-main-watch.js" \ - "npmx nodemon --watch dist/main.js --watch dist/main-server.js --delay 500ms --exec \"node dist/main.js server --host $(or $(BACKEND_HOST),localhost) --port $(or $(BACKEND_PORT),3000)\"" \ + "npmx nodemon --watch dist/cli/index.js --watch dist/cli/server.js --delay 500ms --exec \"node dist/cli/index.js server --host $(or $(BACKEND_HOST),localhost) --port $(or $(BACKEND_PORT),3000)\"" \ "$(SHELL) -lc \"MUX_VITE_HOST=$(or $(VITE_HOST),127.0.0.1) MUX_VITE_PORT=$(or $(VITE_PORT),5173) VITE_BACKEND_URL=http://$(or $(BACKEND_HOST),localhost):$(or $(BACKEND_PORT),3000) vite\"" else dev-server: node_modules/.installed build-main ## Start server mode with hot reload (backend :3000 + frontend :5173). Use VITE_HOST=0.0.0.0 BACKEND_HOST=0.0.0.0 for remote access @@ -145,7 +145,7 @@ dev-server: node_modules/.installed build-main ## Start server mode with hot rel @echo "For remote access: make dev-server VITE_HOST=0.0.0.0 BACKEND_HOST=0.0.0.0" @bun x concurrently -k \ "bun x concurrently \"$(TSGO) -w -p tsconfig.main.json\" \"bun x tsc-alias -w -p tsconfig.main.json\"" \ - "bun x nodemon --watch dist/main.js --watch dist/main-server.js --delay 500ms --exec 'NODE_ENV=development node dist/main.js server --host $(or $(BACKEND_HOST),localhost) --port $(or $(BACKEND_PORT),3000)'" \ + "bun x nodemon --watch dist/cli/index.js --watch dist/cli/server.js --delay 500ms --exec 'NODE_ENV=development node dist/cli/index.js server --host $(or $(BACKEND_HOST),localhost) --port $(or $(BACKEND_PORT),3000)'" \ "MUX_VITE_HOST=$(or $(VITE_HOST),127.0.0.1) MUX_VITE_PORT=$(or $(VITE_PORT),5173) VITE_BACKEND_URL=http://$(or $(BACKEND_HOST),localhost):$(or $(BACKEND_PORT),3000) vite" endif diff --git a/src/browser/api.ts b/src/browser/api.ts index 4314b5c90..d202f5844 100644 --- a/src/browser/api.ts +++ b/src/browser/api.ts @@ -5,8 +5,17 @@ import { IPC_CHANNELS, getChatChannel } from "@/common/constants/ipc-constants"; import type { IPCApi } from "@/common/types/ipc"; // Backend URL - defaults to same origin, but can be overridden via VITE_BACKEND_URL -// This allows frontend (Vite :8080) to connect to backend (:3000) in dev mode -const API_BASE = import.meta.env.VITE_BACKEND_URL ?? window.location.origin; +// This allows frontend (Vite :5173) to connect to backend (:3000) in dev mode +let API_BASE = import.meta.env.VITE_BACKEND_URL ?? window.location.origin; + +// Fix 0.0.0.0 addresses (server bind address) to use actual client hostname +// 0.0.0.0 is not a valid client target - replace with window.location.hostname +if (API_BASE.includes("://0.0.0.0:")) { + const port = API_BASE.split(":").pop(); + const protocol = API_BASE.startsWith("https") ? "https" : "http"; + API_BASE = `${protocol}://${window.location.hostname}:${port}`; +} + const WS_BASE = API_BASE.replace("http://", "ws://").replace("https://", "wss://"); interface InvokeResponse { diff --git a/vite.config.ts b/vite.config.ts index 8a189eda3..d7d0f4649 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -14,6 +14,10 @@ const devServerHost = process.env.MUX_VITE_HOST ?? "127.0.0.1"; // Secure by def const devServerPort = Number(process.env.MUX_VITE_PORT ?? "5173"); const previewPort = Number(process.env.MUX_VITE_PREVIEW_PORT ?? "4173"); +// Allow localhost, 127.0.0.1, and all *.coder domains +// When host is 0.0.0.0, use undefined to allow all hosts (Vite's default for wildcard bind) +const allowedHosts = devServerHost === "0.0.0.0" ? undefined : ["localhost", "127.0.0.1", ".coder"]; + const alias: Record = { "@": path.resolve(__dirname, "./src"), }; @@ -89,7 +93,7 @@ export default defineConfig(({ mode }) => ({ host: devServerHost, // Configurable via MUX_VITE_HOST (defaults to 127.0.0.1 for security) port: devServerPort, strictPort: true, - allowedHosts: devServerHost === "0.0.0.0" ? undefined : ["localhost", "127.0.0.1"], + allowedHosts, sourcemapIgnoreList: () => false, // Show all sources in DevTools watch: { @@ -117,19 +121,12 @@ export default defineConfig(({ mode }) => ({ } }) }, - - hmr: { - // Configure HMR to use the correct host for remote access - host: devServerHost, - port: devServerPort, - protocol: "ws", - }, }, preview: { host: "127.0.0.1", port: previewPort, strictPort: true, - allowedHosts: ["localhost", "127.0.0.1"], + allowedHosts: ["localhost", "127.0.0.1", ".coder"], }, optimizeDeps: { esbuildOptions: { From e7f4eb20a5ac484951079f2fcc351bcffcddb91e Mon Sep 17 00:00:00 2001 From: Jon Ayers Date: Mon, 17 Nov 2025 20:09:37 +0000 Subject: [PATCH 2/2] changes --- vite.config.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/vite.config.ts b/vite.config.ts index d7d0f4649..e943d83ab 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -120,6 +120,12 @@ export default defineConfig(({ mode }) => ({ pollInterval: 100 } }) + }, + hmr: { + // Configure HMR to use the correct host for remote access + host: devServerHost, + port: devServerPort, + protocol: "ws", }, }, preview: {