Pusher Integration for Real-Time Website Notifications
Pusher is a managed WebSocket service. Client subscribes to channels, server publishes events via HTTP API. No WebSocket infrastructure management — only notification logic.
Installation
npm install pusher # server library
npm install pusher-js # client
Server
import Pusher from 'pusher';
const pusher = new Pusher({
appId: process.env.PUSHER_APP_ID,
key: process.env.PUSHER_KEY,
secret: process.env.PUSHER_SECRET,
cluster: process.env.PUSHER_CLUSTER,
useTLS: true
});
// Publish event on order status change
async function notifyOrderUpdate(orderId: string, status: string, userId: string) {
await pusher.trigger(`private-user-${userId}`, 'order-updated', {
orderId,
status,
timestamp: new Date().toISOString()
});
}
// Authorize private channels
app.post('/pusher/auth', authenticate, (req, res) => {
const { socket_id, channel_name } = req.body;
const userId = req.user.id;
// Check user can subscribe to this channel
if (channel_name !== `private-user-${userId}`) {
return res.status(403).json({ error: 'Forbidden' });
}
const auth = pusher.authorizeChannel(socket_id, channel_name);
res.json(auth);
});
Client (React)
import Pusher from 'pusher-js';
import { useEffect, useState } from 'react';
function useOrderNotifications(userId: string) {
const [notifications, setNotifications] = useState([]);
useEffect(() => {
const pusher = new Pusher(process.env.NEXT_PUBLIC_PUSHER_KEY, {
cluster: process.env.NEXT_PUBLIC_PUSHER_CLUSTER,
authEndpoint: '/pusher/auth',
auth: {
headers: { Authorization: `Bearer ${getToken()}` }
}
});
const channel = pusher.subscribe(`private-user-${userId}`);
channel.bind('order-updated', (data) => {
setNotifications(prev => [data, ...prev]);
showToast(`Order #${data.orderId}: ${data.status}`);
});
return () => {
channel.unbind_all();
pusher.unsubscribe(`private-user-${userId}`);
pusher.disconnect();
};
}, [userId]);
return notifications;
}
Presence Channel — Online Statuses
// Who's currently online in room
const channel = pusher.subscribe(`presence-room-${roomId}`, {
userAuthentication: {
params: { userId, userName: user.name }
}
});
channel.bind('pusher:member_added', (member) => {
console.log(`${member.info.userName} joined`);
});
channel.bind('pusher:member_removed', (member) => {
console.log(`${member.info.userName} left`);
});
// Current participants
const members = channel.members;
Limitations and Limits
Pusher Channels: free plan 100 concurrent connections, 200k messages/day. Paid plans start from $49/month.
Alternatives for self-hosted: Soketi (open-source Pusher API compatible).
Timeline
Basic notification integration via Pusher: 1–2 days.







