Skip to main content
The SDK opens a persistent fetch-based SSE connection to GET <baseUrl>/v1/stream after the initial sync completes. The API key is sent as the X-Nexus-API-Key request header - the same header used by all other endpoints. Whenever the Nexus backend emits a change event (config.updated, flag.toggled, resync, …), the SDK triggers an immediate full re-sync - so the in-memory cache is updated within milliseconds of a change. Components subscribed via composables re-render automatically.

Authentication

The Vue SDK sends the API key as the X-Nexus-API-Key header on the stream connection. Unlike the browser EventSource API - which cannot set custom request headers - the fetch API supports headers on streaming responses, so no ?key= query-parameter workaround is needed. The key never appears in the URL, server access logs, or browser history.
Secret keys (wxs_…) are rejected at client-creation time. Only public keys (wxp_…) may be used with browser SDKs.

Vue reactivity integration

Stream events are processed in the fetch reader loop, outside the Vue component lifecycle - but because the SDK’s composables depend on an internal version Ref that’s bumped on every snapshot replacement, this is invisible to your components. When an SSE event triggers a sync, the SDK swaps the snapshot atomically, bumps the version Ref, and Vue’s reactivity system schedules re-renders. You don’t need to do anything special - just use the composables normally.

Reconnection

The SDK manages reconnection itself - it does not rely on the browser EventSource auto-reconnect (there is no EventSource). After a transport failure the SDK schedules a reconnect with exponential backoff (1 s → 30 s capped). Any retry: field sent by the server is ignored. On every (re)connect the server emits a resync event, which causes the SDK to call sync() once and align with the current state. There is no event history; missed events are not replayed. After 3 consecutive transport errors the SDK closes the stream and falls back to TTL polling, emitting FALLBACK_REASON_MAX_ERRORS. The SDK then automatically schedules an SSE reconnect using the sseReconnectCooldown schedule (default: 5 → 10 → 20 → 40 → 60 min). When the timer fires, the failure counter resets and connectStream() is called automatically. (v0.6.0)
Use useNexusStreamStatus() to surface this to users:

429 Too Many Requests

Every project tier has a per-service stream connection limit:

Detection

Because the SDK opens the stream with fetch, it sees the HTTP status directly on the response. When the stream connection returns 429 the SDK:
  1. Emits FALLBACK_REASON_RATE_LIMITED on the stream observer.
  2. Checks for a Retry-After header (delta-seconds, clamped to [5 s, 300 s]):
    • Present: schedules a connectStream() re-entry after the indicated delay.
    • Absent: falls back to TTL polling and schedules reconnect via the sseReconnectCooldown schedule. (v0.6.0)
  3. Does NOT reopen the stream until the delay elapses.
A 429 whose body is {"error":"quarantined"} instead fires onQuarantined(reason, expiresAt) and reconnects after the quarantine window.

Disabling SSE

The SDK calls connectStream() automatically. To opt out at runtime via the imperative client:

Plugin teardown (v0.3.1+)

Both createNexusPlugin().install and provideNexus() wrap the host app.unmount() so that client.disconnectStream() is called automatically when the Vue application is torn down. This aborts the fetch stream, clears any pending reconnect timer, and releases the underlying network connection. You don’t need to do anything as a consumer - teardown is invisible. Two properties of this wrapper are worth knowing about:
  • Errors are swallowed. Any throw from disconnectStream() is caught and logged via console.warn. The wrapper never propagates the error to app.unmount()’s caller.
  • The original unmount always runs. Even if disconnectStream() throws, the wrapped originalUnmount() is still invoked, so Vue’s normal cleanup proceeds.
This matters in two practical scenarios:
  • HMR. Vite / webpack dev servers re-mount the root component on every hot module replacement. Before v0.3.1, each HMR cycle leaked one stream connection. The teardown wrapper now closes the previous stream automatically.
  • SSR / Nuxt 3 app shutdown. When the Nuxt app instance is disposed (e.g. test teardown, dynamic remount), the SSE connection is now released deterministically instead of leaking until GC.

What events trigger a sync

SSR / Nuxt 3

The fetch-based SSE stream is browser-only (the SDK skips it during SSR). In Nuxt 3, register the SDK in a client-only plugin:
The .client.ts suffix tells Nuxt to skip this plugin on the server, so SSR doesn’t try to open the stream.