@night-owl-elite/vue3-ws
v1.0.3
Published
A scalable and reactive Vue 3 Composition API wrapper for Laravel Echo and WebSockets, featuring automatic lifecycle cleanup, dynamic token injection, and native support for Reverb, Pusher, and Soketi.
Downloads
318
Maintainers
Readme
@night-owl-elite/vue3-ws
A scalable and reactive Vue 3 Composition API wrapper for Laravel Echo and WebSockets, featuring automatic lifecycle cleanup, dynamic token injection, and native support for Reverb, Pusher, and Soketi.
Features
- No Memory Leaks: Automatically calls
.stopListening()and leaves channels when Vue components unmount. - Universal Backend Support: Works flawlessly with Pusher Cloud, Laravel Reverb, and Soketi.
- Dynamic Authentication: Pass token getters (e.g., from Pinia or Vuex) so your WebSocket connection always uses the freshest auth state.
- Full Channel Support: First-class methods for Public, Private, and Presence channels.
- Client-to-Client Whispering: Built-in methods for transient states like "User is typing..." indicators.
Installation
Install the package alongside its peer dependencies (laravel-echo and pusher-js):
npm install @night-owl-elite/vue3-ws laravel-echo pusher-js
Getting Started
1. Initialization
Initialize the WebSocket connection once in your application lifecycle. The best place to do this is in your main.js file, or inside your Authentication store after a user logs in.
// src/main.js
import { createApp } from 'vue'
import App from './App.vue'
import { initializeEcho } from '@night-owl-elite/vue3-ws'
const app = createApp(App)
// Example: Initialize Echo
initializeEcho({
// Required:
key: import.meta.env.VITE_PUSHER_APP_KEY,
cluster: import.meta.env.VITE_PUSHER_APP_CLUSTER,
// Optional (Required for self-hosting with Laravel Reverb / Soketi):
host: import.meta.env.VITE_PUSHER_HOST, // e.g., 'localhost'
port: import.meta.env.VITE_PUSHER_PORT, // e.g., 8080
scheme: import.meta.env.VITE_PUSHER_SCHEME, // e.g., 'http' or 'https'
// Authentication Configuration:
authEndpoint: import.meta.env.VITE_WEBSOCKET_ENDPOINT || '/api/broadcasting/auth',
// Dynamic Token Injection (Can be a string or a function)
// Passing a function ensures Echo always gets the latest token if it changes!
token: () => localStorage.getItem('auth_token')
})
app.mount('#app')
2. Usage in Components
Use the useEcho composable anywhere in your Vue 3 application. Because of the built-in automatic lifecycle teardown, you never have to manually clean up your event listeners when a component unmounts.
<script setup>
import { ref } from 'vue';
import { useEcho } from '@night-owl-elite/vue3-ws';
const props = defineProps(['roomId']);
const messages = ref([]);
const onlineUsers = ref([]);
const typingUser = ref(null);
let typingTimeout = null;
const { listenPrivate, whisper, listenWhisper, joinPresence } = useEcho();
const channelName = `chat.${props.roomId}`;
// ----------------------------------------------------
// 1. PRESENCE: Who is online?
// ----------------------------------------------------
joinPresence(channelName, {
onHere: (users) => { onlineUsers.value = users; },
onJoin: (user) => { onlineUsers.value.push(user); },
onLeave: (user) => {
onlineUsers.value = onlineUsers.value.filter(u => u.id !== user.id);
}
});
// ----------------------------------------------------
// 2. LISTENING: Get new messages saved to the database
// ----------------------------------------------------
listenPrivate(channelName, '.MessageSent', (event) => {
messages.value.push(event.message);
});
// ----------------------------------------------------
// 3. WHISPERING: Typing Indicators (Bypasses Database)
// ----------------------------------------------------
const handleTyping = () => {
// Tell other clients in this private room we are typing
whisper(channelName, 'typing', { name: 'CurrentUserName' });
};
// Listen for others whispering
listenWhisper(channelName, 'typing', (data) => {
typingUser.value = data.name;
// Clear the typing indicator after 2 seconds of silence
clearTimeout(typingTimeout);
typingTimeout = setTimeout(() => {
typingUser.value = null;
}, 2000);
});
</script>
<template>
<div class="chat-room">
</div>
</template>
API Reference
initializeEcho(config: Object)
Bootstraps the global Laravel Echo instance.
key (String): Pusher/Reverb App Key.
cluster (String): Pusher Cluster.
token (String | Function): Bearer token for private/presence channels. Can be a static string or a callback function returning a string.
host (String): Custom WebSocket host (Required for Reverb/Soketi).
port (Number): Custom WebSocket port (Required for Reverb/Soketi).
scheme (String): http or https (Defaults to https).
forceTLS (Boolean): Force TLS connection (Defaults to true).
authEndpoint (String): The backend URL used to authorize private/presence channels.
useEcho()
Returns the following reactive methods:
echo: The raw Laravel Echo instance (useful if you need advanced Echo features not covered by the wrapper).
listenPublic(channelName, eventName, callback): Subscribe to a public channel.
listenPrivate(channelName, eventName, callback): Subscribe to a private, authenticated channel.
joinPresence(channelName, { onHere, onJoin, onLeave }): Join a presence channel and track online users.
whisper(channelName, whisperName, data): Broadcast client-to-client data without hitting the database.
listenWhisper(channelName, whisperName, callback): Listen for client-to-client broadcasts.