Skip to main content

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.
Closed beta. Embedding the subscribe widget in your own app is enabled per organisation and is off by default. The packages below are published, but the Subscribe widget screen in your dashboard shows a preview instead of a configuration form until the feature is switched on. Ask your Notifizz contact to enable it for your project.

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 (secure or public), and the subscriber id of the signed-in user.
  • Each mount needs a resourceId, plus a hash when the environment is in secure mode — 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

Two components pointing at the same 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 no destroy() 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

Pair mount() 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:
The loader installs a queue immediately, so calls made before the widget finishes downloading are replayed in order — the 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 from https://widget.notifizz.com and call https://api.notifizz.com. Allow both:
The React package loads no script — it only needs 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

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.
No. Unmounting removes UI. The subscription is a durable record and only the button removes it.
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.
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.
Not today. Use @notifizz/subscribe-vanilla from a directive or a component, pairing mount() with ngOnDestroy.
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.
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.