Vue Plugin for Server-Sent Events
vue-sse is a Vue plugin designed to simplify the consumption of Server-Sent Events (SSE) within Vue 2 and Vue 3 applications. It provides a high-level, fluent API wrapper around the native `EventSource` web API, abstracting away much of the low-level EventSource management. The package is currently at version 2.5.2 and appears to be actively maintained, offering features like automatic message formatting (plain, JSON, or custom), credential handling for CORS, and optional EventSource polyfilling for broader browser compatibility. Its core differentiator is the seamless integration into the Vue ecosystem, exposing an `$sse` instance property on Vue components and the Vue global object for easy client creation and event handling. It's built for reactive handling of server-pushed data streams.
Common errors
-
Uncaught TypeError: Cannot read properties of undefined (reading 'create') (or: TypeError: this.$sse is undefined)
cause The `vue-sse` plugin was not correctly installed via `app.use(VueSSE)` (Vue 3) or `Vue.use(VueSSE)` (Vue 2), or `$sse` was accessed outside a Vue component instance or the global Vue object context.fixEnsure `app.use(VueSSE)` (Vue 3) or `Vue.use(VueSSE)` (Vue 2) is called before components attempt to access `$sse`. Also, confirm access is within a component instance (e.g., `this.$sse`) or the global Vue object (`Vue.$sse`). -
Failed to make initial connection: <error message>
cause The initial HTTP request to establish the SSE connection failed, possibly due to network issues, an incorrect URL, CORS policy, or server unavailability.fixVerify the SSE endpoint URL is correct and accessible. Check browser developer tools for network errors (e.g., 404, 500, CORS preflight failures). Ensure the server is running and configured to handle SSE requests. -
Failed to parse or lost connection: <error message>
cause An error occurred during the event stream, such as a lost connection, an unparseable message when `format: 'json'` is active, or an internal `EventSource` error.fixInspect the `err` object for details. If it's a parsing error, check server-side output format and `vue-sse` `format` option. If it's a connection loss, consider server stability, network conditions, or browser-specific `EventSource` limitations. -
EventSource error: <details>
cause A generic `EventSource` error occurred that was not specifically caught by `on('error')` handlers, or a warning from the browser's native `EventSource` implementation.fixImplement a comprehensive `on('error', (err) => { ... })` handler on your `SSEClient` instance to catch and log all stream-related errors. Review browser console for additional context about the `EventSource` issue.
Warnings
- gotcha Failure to explicitly call `client.disconnect()` in lifecycle hooks (e.g., `beforeUnmount` for Vue 3 or `beforeDestroy` for Vue 2) will lead to persistent open connections, potential memory leaks, and unnecessary server load.
- gotcha The `connect()` method must be explicitly called on the `SSEClient` instance to initiate the connection to the Server-Sent Events endpoint. Connections are not automatically established upon client creation.
- gotcha If `format: 'json'` is specified for the client or globally, incoming messages are expected to be valid JSON. Non-JSON messages will trigger an `error` event with parsing failures instead of a `message` event.
- gotcha When using the `polyfill` option, understand the difference between `polyfill: true` (which uses the native EventSource if available) and `forcePolyfill: true` (which always uses the polyfill, potentially hiding native browser issues or behaviors).
Install
-
npm install vue-sse -
yarn add vue-sse -
pnpm add vue-sse
Imports
- VueSSE
const VueSSE = require('vue-sse');import VueSSE from 'vue-sse';
- SSEClient
import { SSEClient } from 'vue-sse';import type { SSEClient } from 'vue-sse'; - VueSSEConfig
import { VueSSEConfig } from 'vue-sse';import type { VueSSEConfig } from 'vue-sse';
Quickstart
// main.ts
import { createApp, type App } from 'vue'; // For Vue 3
// For Vue 2, use: import Vue from 'vue';
import VueSSE from 'vue-sse';
import type { SSEClient } from 'vue-sse'; // For typing sseClient
const app: App = createApp({
template: `
<div style="font-family: sans-serif; padding: 20px;">
<h1>Vue SSE Example</h1>
<p>Status: {{ status }}</p>
<p>Last Message: <pre>{{ lastMessage ? JSON.stringify(lastMessage, null, 2) : 'None' }}</pre></p>
<p v-if="error" style="color: red;">Error: {{ error }}</p>
<button @click="connect" :disabled="isConnected">Connect</button>
<button @click="disconnect" :disabled="!isConnected">Disconnect</button>
</div>
`,
data() {
return {
status: 'Disconnected',
lastMessage: null as any,
error: null as string | null,
sseClient: null as SSEClient | null,
isConnected: false
};
},
methods: {
connect() {
if (this.sseClient) {
this.sseClient.disconnect(); // Ensure previous is closed
}
this.status = 'Connecting...';
this.error = null;
this.sseClient = this.$sse.create({
url: 'https://demo.websocket.me/sse', // Public SSE demo endpoint
format: 'json'
});
this.sseClient
.on('message', (msg: any) => {
console.info('SSE Message:', msg);
this.lastMessage = msg;
this.status = 'Connected & Receiving';
})
.on('error', (err: Error) => {
console.error('SSE Error:', err);
this.error = err.message || 'SSE connection error';
this.status = 'Error';
this.isConnected = false;
})
.connect()
.then(() => {
console.log('SSE client connected successfully.');
this.status = 'Connected';
this.isConnected = true;
})
.catch((err: Error) => {
console.error('Failed to make initial SSE connection:', err);
this.error = err.message || 'Initial connection failed';
this.status = 'Failed to Connect';
this.isConnected = false;
});
},
disconnect() {
if (this.sseClient) {
this.sseClient.disconnect();
this.status = 'Disconnected';
this.isConnected = false;
console.log('SSE client disconnected.');
}
}
},
mounted() {
// Initial connection attempt or call connect() on button click
this.connect();
},
beforeUnmount() { // Use beforeDestroy() for Vue 2
this.disconnect();
}
});
// Install the VueSSE plugin globally
app.use(VueSSE);
// For Vue 2, use: Vue.use(VueSSE);
app.mount('#app');