Table of Contents

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

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.

Correct configuration

// 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',
},

Why it is easy to miss

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.

Checking a full proxy block

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.