@notifizz/subscribe-react
v2.0.1
Published
React components and hooks for the Notifizz subscribe widget — multi-instance per page
Readme
@notifizz/subscribe-react
Native React components and hooks for the Notifizz subscribe widget. Multi-instance per page — mount one per Kanban card, one per thread, one per resource. State is shared automatically when two components point to the same resource.
Install
npm install @notifizz/subscribe-reactPeer dependency: React 18 or 19.
Quick start
Wrap your app once with <NotifizzProvider>:
import { NotifizzProvider } from '@notifizz/subscribe-react';
<NotifizzProvider
apiKey={import.meta.env.VITE_NOTIFIZZ_API_KEY}
mode="secure"
subscriberId={user.email}
>
<App />
</NotifizzProvider>Drop <NotifizzSubscribe> anywhere you want a button + avatars:
import { NotifizzSubscribe } from '@notifizz/subscribe-react';
<NotifizzSubscribe resourceId="proj_42" hash={hashForProj42} />Multi-instance — N widgets per page
function Kanban({ projects }: { projects: Project[] }) {
return (
<div className="grid">
{projects.map((p) => (
<Card key={p.id}>
<h3>{p.name}</h3>
<NotifizzSubscribe resourceId={p.id} hash={p.subscribeHash} />
</Card>
))}
</div>
);
}Two components on the same resourceId (e.g. a card + a detail panel) automatically sync — clicking subscribe in one updates the other without a refetch.
Generating the hash (secure mode)
Server-side, via a Notifizz backend SDK:
// Node.js
const hash = notifizz.generateSubscribeToken(subscriberId, resourceId);Pass it as a prop from your server-side rendered page or fetched from your backend.
In public mode, no hash is needed.
Custom UI with useSubscription
If you need a different layout, the <NotifizzSubscribe> default doesn't fit, or you want full control:
import { useSubscription } from '@notifizz/subscribe-react';
function MyCustomButton({ resourceId, hash }: { resourceId: string; hash: string }) {
const {
isSubscribed,
subscriberCount,
subscribers,
isLoading,
toggle,
} = useSubscription(resourceId, hash);
return (
<button onClick={toggle} disabled={isLoading}>
{isSubscribed ? '★' : '☆'} {subscriberCount}
</button>
);
}The hook returns:
| Field | Type |
|---|---|
| isSubscribed | boolean |
| subscribers | SubscriberInfo[] |
| subscriberCount | number |
| isLoading | boolean (shared per resource — true while a refresh is in flight) |
| subscribe() | () => Promise<void> |
| unsubscribe() | () => Promise<void> |
| toggle() | () => Promise<void> |
| refresh() | () => Promise<void> |
Custom avatar rendering — renderSubscriber
Useful when subscribers' display name lives outside the Notifizz store (e.g. Clerk, Auth0):
import { useOrgMembers } from './clerk-helpers';
function ProjectSubscribe({ id, hash }: { id: string; hash: string }) {
const { members } = useOrgMembers();
return (
<NotifizzSubscribe
resourceId={id}
hash={hash}
renderSubscriber={(sub) => {
const member = members.find((m) => m.userId === sub.id);
return (
<img
src={member?.imageUrl}
alt={member?.fullName}
title={member?.fullName ?? sub.id}
style={{ width: 28, height: 28, borderRadius: '50%' }}
/>
);
}}
/>
);
}By default, subscribers are rendered as colored circles with their initial (or avatarUrl if provided in the subscriber payload).
API
<NotifizzProvider>
| Prop | Required | Default |
|---|---|---|
| apiKey | ✅ | — |
| mode | ✅ | — ('public' | 'secure') |
| subscriberId | ✅ | — (typically the current user's email) |
| apiUrl | | https://api.notifizz.com/v1 |
| maxAvatars | | 5 |
<NotifizzSubscribe>
| Prop | Required | Notes |
|---|---|---|
| resourceId | ✅ | |
| hash | If mode === 'secure' | HMAC hash for this (subscriberId, resourceId) pair |
| renderSubscriber | | Custom avatar renderer (sub) => ReactNode |
| subscribeLabel / unsubscribeLabel | | Override brand labels |
| maxAvatars | | Override brand value |
| className / style | | Wrap inline styles |
useSubscription(resourceId, hash?)
See "Custom UI" section above.
Lifecycle in SPAs
React handles lifecycle automatically — when a <NotifizzSubscribe> unmounts, the underlying subscription is cleaned up. No destroy() call needed.
If a parent re-renders with a new resourceId, the component re-subscribes to the new resource. State of the old resource stays in the module cache (other components on it remain in sync).
See also
@notifizz/subscribe-vanilla— JS/TS wrapper, multi-instance, framework-agnostic@notifizz/subscribe-angular— Angular component- Documentation: https://docs.notifizz.com/sdks/subscribe (coming soon)
