react-use-pusher v0.5.0
react-use-pusher
Easy as React hooks that integrate with the
pusher-js
library.
- Install
- Usage
useChannel
usePrivateChannel
usePresenceChannel
useEvent
useClientTrigger
usePusher
Authentication Example
Install
npm install react-use-pusher
Usage
You must wrap your app with a PusherProvider
and pass it config props for pusher-js
initialisation.
import React from 'react';
import { PusherProvider } from 'react-use-pusher';
const App = () => {
<PusherProvider
clientKey={process.env.CLIENT_KEY}
cluster="eu"
// you can set this to false if you're waiting on some state to load
// and want to wait for it before the WS connection happens
ready
// if you're using presence channels
// see: https://pusher.com/docs/channels/server_api/authorizing-users/#implementing-the-authorization-endpoint-for-a-presence-channel
channelAuthEndpoint="/api/auth"
// TIP: if you're hosting your own websocket server via something like Soketi
// you can pass additional pusher options for the websocket connection via the prop bellow
// recommend you either memoise these options or
// use a statically defined object outside the component if possible
// options={{ wsHost: 'MY_HOST', wssPort: 1234, wsPort:1233, wsPath: '/my-path' }}
>
<Example />
</PusherProvider>;
};
useChannel
Use this hook to subscribe to a channel.
// returns Channel instance.
const channel = useChannel('channel-name');
usePrivateChannel
Use this hook to subscribe to a private channel.
If you're using presence channels, you must provide an auth endpoint.
See the Pusher Docs for examples for how the endpoint is implemented.
// returns PrivateChannel instance.
const channel = usePrivateChannel('private-name');
usePresenceChannel
Presence channels allow you to see who else is connected
If you're using presence channels, you must provide an auth endpoint.
See the Pusher Docs for examples for how the endpoint is implemented.
const Example = () => {
const { members, myID } = usePresenceChannel('presence-dashboard');
return (
<ul>
{members
// filter self from members
.filter(({ id }) => id !== myID)
// map them to a list
.map(({ id, name }) => (
<li key={id}>{name}</li>
))}
</ul>
);
};
useEvent
Bind to events on a channel with a callback.
const Example = () => {
const [message, setMessages] = useState();
const channel = useChannel('channel-name');
useEvent(channel, 'event name', (data) => console.log(data));
};
Note: This will bind and unbind to the event on each render. You may want to memoise your callback with useCallback
before passing it in.
useClientTrigger
Message other clients directly. use client events to push directly from the client:
import { useChannel, useClientTrigger } from 'react-use-pusher';
const Example = () => {
const channel = useChannel('presence-dashboard');
const trigger = useClientTrigger(channel);
const handleClientEvent = () => {
trigger('event name', eventData);
};
return <button onClick={handleClientEvent}>Fire</button>;
};
usePusher
Get access to the Pusher instance to do other things.
import { usePusher } from 'react-use-pusher';
const Example = () => {
const { client } = usePusher();
return null;
};
Authentication endpoint example
I'm using a NextJS api endpoint page as an example.
npm install pusher
// pages/api/auth.ts
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type { NextApiRequest, NextApiResponse } from 'next';
import Pusher from 'pusher';
type Modify<T, K extends keyof T, U> = Omit<T, K> & {
[P in keyof Pick<T, K>]: U;
};
type AuthBody = {
socket_id: string;
channel_name: string;
[key: string]: unknown;
};
const pusher = new Pusher({
appId: process.env.APP_ID,
key: process.env.APP_KEY,
secret: process.env.APP_SECRET,
cluster: 'eu',
});
export default function handler(
req: Modify<NextApiRequest, 'body', AuthBody>,
res: NextApiResponse,
) {
const { socket_id, channel_name, ...rest } = req.body;
const channelData = {
// user_id is mandatory according to pusher docs
user_id: 'the user id',
user_info: {
// name within user_info is mandatory
name: 'the authenticated user name',
// you can put whatever you like here. It'll appear in the presence channel member's data
...rest,
},
};
res.status(200).json(pusher.authorizeChannel(socket_id, channel_name, channelData));
}