Pusher Channels JavaScript Client
The `pusher-js` library provides a robust client-side solution for real-time communication via Pusher Channels. It supports a wide array of JavaScript environments, including web browsers, React Native, Node.js, and web workers, offering a consistent API across platforms. Currently at stable version 8.5.0, the library demonstrates an active release cadence, frequently delivering security updates via dependency pinning and introducing new features like the `switchCluster` method for dynamic cluster changes without disrupting existing channel subscriptions. Its key differentiators include extensive platform compatibility, resilient fallback mechanisms (WebSockets, HTTP), and dedicated support for both public and private channels, including an optional build specifically for encrypted channels. It is designed purely for client-side interaction with the Pusher service, distinct from the `pusher-http-node` server-side library.
Common errors
-
Module not found: Can't resolve 'pusher-js/with-encryption'
cause Attempting to use encrypted channels without the correct import path.fixEnsure you are importing from `pusher-js/with-encryption` for encrypted channel support, instead of the default `pusher-js` path. -
Pusher: Auth handler not provided for private/presence channel
cause Attempting to subscribe to a `private-` or `presence-` channel without providing a `userAuthentication` or `channelAuthorization` callback in the Pusher client options.fixConfigure an authentication endpoint or a custom `userAuthentication` / `channelAuthorization` function in your Pusher client initialization options to authorize access to private/presence channels. -
Pusher: Unknown host: ws-mt1.pusher.com
cause Incorrect cluster name provided during Pusher client initialization, leading to an inability to resolve the WebSocket endpoint.fixDouble-check the `cluster` option when initializing Pusher (e.g., `'eu'`, `'us2'`, `'ap2'`) against your Pusher dashboard settings. Ensure it's a valid Pusher cluster. -
Pusher: WebSocket connection failed: Event { isTrusted: true, type: 'error', ... }cause The WebSocket connection could not be established, often due to network issues, incorrect app key, invalid TLS settings (e.g., `forceTLS: false` with HTTPS origin), or firewall restrictions.fixVerify your `appKey` and `cluster` are correct. Ensure `forceTLS: true` is set if your application is served over HTTPS. Check browser console for more specific WebSocket errors and network connectivity.
Warnings
- gotcha For encrypted channels, you must explicitly import from `pusher-js/with-encryption`. The default `pusher-js` import does not include the necessary encryption primitives to keep bundle sizes down.
- breaking The `AuthOptionsT` type was refactored to a discriminated union (`InternalAuthOptions | CustomAuthOptions`) in v8.5.0 for improved type safety. This might cause TypeScript compilation errors if you have custom authentication handlers or intricate type definitions related to `AuthOptionsT`.
- gotcha Versions prior to 8.5.0 might not correctly persist custom options (like authentication handlers) when using the `switchCluster` method, which was introduced in 8.4.0-rc1. This could lead to unexpected behavior or disconnections upon cluster switching.
- breaking Multiple security vulnerabilities in transitive dependencies (e.g., `express`, `qs`, `lodash`, `node-forge`) were patched in versions 8.4.1 and 8.4.3. Older versions are susceptible to these known CVEs.
Install
-
npm install pusher-js -
yarn add pusher-js -
pnpm add pusher-js
Imports
- Pusher
const Pusher = require('pusher-js');import Pusher from 'pusher-js';
- Pusher (with encryption)
import Pusher from 'pusher-js';
import Pusher from 'pusher-js/with-encryption';
- Pusher (CommonJS)
import Pusher from 'pusher-js';
const Pusher = require('pusher-js');
Quickstart
import Pusher from 'pusher-js';
// Replace with your actual Pusher app key and cluster
const PUSHER_APP_KEY = process.env.PUSHER_APP_KEY ?? 'YOUR_APP_KEY';
const PUSHER_APP_CLUSTER = process.env.PUSHER_APP_CLUSTER ?? 'eu'; // e.g., 'eu', 'us2'
if (PUSHER_APP_KEY === 'YOUR_APP_KEY') {
console.warn('Pusher app key not set. Using a placeholder. Replace YOUR_APP_KEY and PUSHER_APP_CLUSTER with your actual credentials.');
}
const pusher = new Pusher(PUSHER_APP_KEY, {
cluster: PUSHER_APP_CLUSTER,
forceTLS: true // Always use TLS for production
});
pusher.connection.bind('connected', () => {
console.log('Pusher client connected!');
});
pusher.connection.bind('disconnected', () => {
console.log('Pusher client disconnected!');
});
const channel = pusher.subscribe('my-channel');
channel.bind('my-event', function(data: any) {
console.log('Received event on my-channel:', data);
});
// To simulate receiving an event (typically sent from a server):
// setTimeout(() => {
// console.log('Simulating event trigger...');
// // This part would typically be handled by your server sending an event
// // For client-side simulation, you might use a debug API or similar.
// }, 5000);
console.log('Pusher client initialized and attempting to connect...');
// You can switch cluster dynamically (since v8.5.0)
// setTimeout(() => {
// console.log('Switching cluster to us2...');
// pusher.switchCluster('us2');
// }, 10000);