Subscribe widget
A button and a stack of avatars, mounted next to whatever your users can follow. Clicking it records a subscription; clicking it again removes one. Mount as many as the page has resources — instances watching the same resource share their state, so subscribing on a card updates the detail panel without a refetch. This page is for developers. The backend half — minting the token that authorises a mount — is subscriptions from your backend.TL;DR
- React —
@notifizz/subscribe-react. A provider, a drop-in component, and a hook for custom UI. No script tag, nothing injected into the page. - Everything else —
@notifizz/subscribe-vanilla. Loads the widget script for you and returns a handle per mount. - Both need three things at the top: the front API key, the mode (
secureorpublic), and the subscriber id of the signed-in user. - Each mount needs a
resourceId, plus ahashwhen the environment is insecuremode — computed by your backend. - N components on one resource make one network request, not N, and stay in sync with each other.
- Appearance — colour, labels, avatar count — is set once in the dashboard, not per mount.
The three packages
Pick the wrapper for your stack.
@notifizz/subscribe is worth installing only when you drive the widget through the script tag and want its types in your editor.
Both wrappers follow the SDK versioning policy — pin to a major.
React
Provide the identity once
<NotifizzProvider> holds what does not change between mounts. Place it once, above everything that renders a subscribe button, after the user is authenticated:
Rendering a subscribe component outside the provider throws immediately rather than failing silently later.
Drop in the button
Missing a required prop throws at render — into the nearest error boundary — rather than producing a
401 you have to find in the network tab.
One per resource, any number per page
resourceId — a card and the detail panel it opens — share one store. Clicking subscribe in one updates the other with no refetch, and mounting both in the same tick fires a single request for the subscriber list.
Custom UI with useSubscription
When the default button does not fit, take the state and render your own:
useSubscription powers <NotifizzSubscribe>, so mixing the two on one resource is fine — they read the same store.
Naming the avatars
By default an avatar is the first character of whatever the subscription holds, coloured deterministically from the id. Since a subscription created by the widget stores only the subscriber id, that usually means the first character of the id — legible, but not a name. That is on purpose: Notifizz is not the place your user directory lives. Render the names from wherever they already are:Lifecycle
React handles it. Unmounting a component detaches its listener; there is nodestroy() to call. Changing resourceId re-points the component at the new resource, and the previous resource’s state stays in the shared store for whatever else is watching it.
Unmounting a component does not unsubscribe the person. Only pressing the button does.
Vanilla JS and TypeScript
For Angular, Vue, Svelte, server-rendered pages, or anything else. The wrapper injects the widget script the first time you call it and returns a handle per mount.createSubscribe(options)
Calling
createSubscribe() more than once is safe — the script is injected once and shared.
mount(options)
Returns a handle:
subscribe.destroy() tears down every instance created by that subscribe object. It deliberately leaves the script in place — a later mount reuses it.
mount() rejects when the script fails to load within readyTimeoutMs (network or CSP), when the container is missing or already has a widget, or when secure mode is on and no hash was supplied.
Lifecycle in a component framework
Pairmount() with your framework’s teardown hook, and guard against the component disappearing while the promise is in flight:
Script tag and auto-mount
For server-rendered pages with no build step. Load the loader, mark the elements, initialise once:init above does not need to wait for anything.
With autoMount left on (the default for this path), the widget scans for [data-notifizz-subscribe] and keeps watching: elements injected later, by a template fragment or an innerHTML update, are mounted as they appear.
Driving it imperatively
The same global takes commands:
Per-instance operations live on the handle, never on the global — a page with twenty widgets has no meaningful notion of the current one.
Two ways to know the API is live, if you need to call
mount immediately rather than queue it: the notifizz-subscribe:ready event on window, or the synchronous flag window._notifizzSubscribe._ready.
Content Security Policy
The Vanilla and script-tag paths load a script fromhttps://widget.notifizz.com and call https://api.notifizz.com. Allow both:
connect-src.
Appearance
Set once for the whole organisation, in the dashboard under Settings → Subscribers & privacy → Subscribe widget, with a live preview. Every mounted widget fetches it once per page load and caches it, so N instances cost one request.
Two notes on what applies where. Avatar position and border style are applied by the loader-based widget — the Vanilla and script-tag paths; the React package renders avatars on the left with rounded controls. And per-mount props always win:
subscribeLabel, unsubscribeLabel and maxAvatars on <NotifizzSubscribe> override the dashboard for that instance.
Because appearance is cached per page load, a change made in the dashboard shows up on the next reload, not in an open tab.
Failure modes
FAQ
Can I use the widget without a signed-in user?
Can I use the widget without a signed-in user?
Only in
public mode, and only for resources with no privacy or authorisation stake — anonymous subscribers still need a stable subscriberId, and in public mode any browser can claim any id. Anything behind a login belongs in secure mode.Does unmounting the widget unsubscribe the person?
Does unmounting the widget unsubscribe the person?
No. Unmounting removes UI. The subscription is a durable record and only the button removes it.
How many widgets can one page carry?
How many widgets can one page carry?
As many as it has resources. Mounts on the same resource share one request and one store, and appearance is fetched once for the page — the cost of the twentieth widget is a DOM node.
Can I read the subscriber list without rendering anything?
Can I read the subscriber list without rendering anything?
In React, yes —
useSubscription(resourceId, hash) gives you the list with no markup attached. In the Vanilla package the list arrives through a mounted handle, so mount into a hidden container if you only want the data.Is there an Angular package?
Is there an Angular package?
Not today. Use
@notifizz/subscribe-vanilla from a directive or a component, pairing mount() with ngOnDestroy.Which package should I install if I already use the notification center?
Which package should I install if I already use the notification center?
The subscribe packages are independent of the notification-center ones — different scripts, different endpoints, different purpose. Installing both is normal, and neither interferes with the other.
The avatar stack is empty even though I just subscribed.
The avatar stack is empty even though I just subscribed.
Subscribe and unsubscribe do not throw in the browser; they rely on the refresh that follows to reconcile with the server. An empty stack after a click almost always means the write was refused — check the response status of the subscribe call, then the hash.
See also
Subscriptions from your backend
Minting the hash, and notifying a group.
Subscriptions
What a subscription is and how it becomes a notification.
API keys
Where the Front API Key comes from.
Versioning policy
How these packages are versioned and released.