With --public-url the browser is told to reach the server at the public origin, which is the Vite dev port. Vite forwarded /api, /.well-known and /attachments but nothing upgraded websockets, so the client's RPC socket at /ws was answered by Vite instead of the server and closed before it opened. Every RPC then failed and the app reported the server as not connected — "siva is not connected" on the provider dialog, which reads as a Hermes fault but is the whole transport being down. Loopback dev never hit this because the client talks to the server port directly; only the reverse-proxied path routes through Vite. Add a /ws rule with ws: true, and set ws: true on /api as well since it carries the Hermes gateway socket at /api/hermes-gateway/ws. Verified against the running dev server: a real websockets client now completes the upgrade through the proxy and gets a structured connection.rejected / enrollment-expired from the broker for a bogus token, where previously the connection was dropped before the handshake.
Unified · Split
| @@ -149,14 +149,28 @@ export default defineConfig(() => { · 148 unmodified lines | |||
| 149 | target: devProxyTarget, | 149 | target: devProxyTarget, |
| 150 | changeOrigin: true, | 150 | changeOrigin: true, |
| 151 | }, | 151 | }, |
| 152 | // `ws: true` because /api carries the Hermes gateway socket at | ||
| 153 | // /api/hermes-gateway/ws alongside plain HTTP routes. | ||
| 152 | "/api": { | 154 | "/api": { |
| 153 | target: devProxyTarget, | 155 | target: devProxyTarget, |
| 154 | changeOrigin: true, | 156 | changeOrigin: true, |
| 157 | ws: true, | ||
| 155 | }, | 158 | }, |
| 156 | "/attachments": { | 159 | "/attachments": { |
| 157 | target: devProxyTarget, | 160 | target: devProxyTarget, |
| 158 | changeOrigin: true, | 161 | changeOrigin: true, |
| 159 | }, | 162 | }, |
| 163 | // The client's RPC socket. Without a forwarding rule the upgrade | ||
| 164 | // is answered by Vite rather than the server, so a browser told | ||
| 165 | // to use the public origin (`--public-url`) connects to the Vite | ||
| 166 | // port and every RPC fails — the whole app reports the server as | ||
| 167 | // not connected. Loopback dev never hit this because the client | ||
| 168 | // talks to the server port directly. | ||
| 169 | "/ws": { | ||
| 170 | target: devProxyTarget, | ||
| 171 | changeOrigin: true, | ||
| 172 | ws: true, | ||
| 173 | }, | ||
| 160 | }, | 174 | }, |
| 161 | } | 175 | } |
| 162 | : {}), | 176 | : {}), |