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 theX-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 thefetch 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 browserEventSource 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)
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 withfetch, it sees the HTTP status directly on the response. When the stream connection returns 429 the SDK:
- Emits
FALLBACK_REASON_RATE_LIMITEDon the stream observer. - Checks for a
Retry-Afterheader (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
sseReconnectCooldownschedule. (v0.6.0)
- Present: schedules a
- Does NOT reopen the stream until the delay elapses.
{"error":"quarantined"} instead fires onQuarantined(reason, expiresAt) and reconnects after the quarantine window.
Disabling SSE
The SDK callsconnectStream() automatically. To opt out at runtime via the imperative client:
Plugin teardown (v0.3.1+)
BothcreateNexusPlugin().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 viaconsole.warn. The wrapper never propagates the error toapp.unmount()’s caller. - The original
unmountalways runs. Even ifdisconnectStream()throws, the wrappedoriginalUnmount()is still invoked, so Vue’s normal cleanup proceeds.
- 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:.client.ts suffix tells Nuxt to skip this plugin on the server, so SSR doesn’t try to open the stream.