Skip to content

Vite Configuration

When you use Vite’s built-in dev server to proxy API requests to a backend running on a different port, WebSocket connections require explicit opt-in.

WebSocket proxy for the observable query hub

Section titled “WebSocket proxy for the observable query hub”

Vite’s proxy is built on http-proxy. By default it only proxies regular HTTP requests. To also forward the WebSocket upgrade handshake that the observable query hub requires, you must set ws: true on every proxy rule whose target serves WebSocket connections.

The hub endpoint is /.cratis/queries/ws. Without ws: true on the /.cratis proxy rule, the browser issues a WebSocket upgrade to the Vite dev server, but Vite returns a plain HTTP response and the connection fails. Observable queries silently receive no data and repeatedly attempt to reconnect.

vite.config.ts
export default defineConfig({
server: {
proxy: {
'/.cratis': {
target: 'http://localhost:5001',
ws: true, // required for WebSocket upgrade
},
},
},
});

Compare with a common incorrect configuration that handles only HTTP:

// ❌ Missing ws: true — WebSocket connections fail silently
'/.cratis': {
target: 'http://localhost:5001',
},

Most proxy rules are added to forward fetch and XHR traffic. Those work without ws: true because they are ordinary HTTP requests. Observable queries are the only part of Arc that upgrade to a WebSocket, so the missing flag goes unnoticed until you observe that live data is never delivered to the frontend.

Vite docs: Server options — proxy.

A typical Vite setup that exposes both the REST API and the observable query hub looks like this:

server: {
proxy: {
'/api': {
target: 'http://localhost:5001',
ws: true, // required if any /api route also uses WebSocket
},
'/.cratis': {
target: 'http://localhost:5001',
ws: true, // required for /.cratis/queries/ws
},
},
},

Neither rule needs changeOrigin: true when the backend is on the same machine.