> ## Documentation Index
> Fetch the complete documentation index at: https://notifizz.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Notifizz Widget Bridge Reference

> Programmatic command/event surface for the Notifizz widget — BRIDGE_COMMANDS, BRIDGE_EVENTS, NotifizzState. Drive the widget from any framework.

# Widget bridge reference

The Notifizz widget exposes a programmatic command/event surface — `BRIDGE_COMMANDS` for sending instructions to the widget, `BRIDGE_EVENTS` for listening to its state. The three frontend SDKs (`@notifizz/react`, `@notifizz/angular`, `@notifizz/vanilla`) all wrap this same surface; this page documents it directly so you can integrate the widget from any runtime.

## TL;DR

* **`window.notifizz(command, ...args)`** — invoke a bridge command.
* **`window.addEventListener("notifizz:ready", cb)`** — fires once when the widget is loaded and authenticated.
* **`window.addEventListener("notifizz:state", cb)`** — fires on every state change with `event.detail: NotifizzState`.
* The contract lives in `sdk/shared/contract.ts` — single source of truth for both the widget and every SDK.

## Public commands

`BRIDGE_COMMANDS` are the public, supported instructions. They're the same across React, Angular, and Vanilla.

| Command                        | Args                                                           | Description                                               |
| ------------------------------ | -------------------------------------------------------------- | --------------------------------------------------------- |
| `authenticateWithFirebase`     | `{ apiKey, token, ...userFields? }`                            | Authenticate the widget session with a Firebase ID token. |
| `authenticateWithBackendToken` | `{ apiKey, token, userId, userEmail, ...additional? }`         | Authenticate with an HMAC token minted server-side.       |
| `authenticateWithNone`         | `{ apiKey, userId, userEmail }`                                | Dev-only — no token verification.                         |
| `setPosition`                  | `'top-right' \| 'top-left' \| 'bottom-right' \| 'bottom-left'` | Move the bell to one of four screen corners.              |
| `setNotificationCenterStyles`  | `{ marginTop?: string }`                                       | Adjust the notification-center dropdown placement.        |
| `setBellStyles`                | `{ marginRight?: string; marginLeft?: string }`                | Adjust bell placement.                                    |
| `toggle`                       | none                                                           | Toggle the dropdown open/closed.                          |
| `open`                         | none                                                           | Open the dropdown.                                        |
| `close`                        | none                                                           | Close the dropdown.                                       |
| `getState`                     | `(state: NotifizzState) => void`                               | Read the current state synchronously via callback.        |

```javascript theme={null}
// Drive the widget directly from any runtime
window.notifizz("setPosition", "top-right");
window.notifizz("toggle");
window.notifizz("getState", (state) => console.log(state.unreadCount));
```

<Note>
  A few internal commands (e.g. `setBellIcon`, `setRoundedButton`) live in a separate internal registry and are not part of `BRIDGE_COMMANDS`. They're used by the SDK packages and may change without notice — don't call them from your code.
</Note>

## Public events

`BRIDGE_EVENTS` are dispatched on `window`:

| Event            | Payload (`event.detail`) | Description                                                                                       |
| ---------------- | ------------------------ | ------------------------------------------------------------------------------------------------- |
| `notifizz:ready` | none                     | Fires **once** when the widget is loaded and authenticated. After this, `state.isReady === true`. |
| `notifizz:state` | `NotifizzState`          | Fires on every state change. Subscribe to keep your UI in sync.                                   |

```javascript theme={null}
window.addEventListener("notifizz:ready", () => {
  console.log("widget ready");
});

window.addEventListener("notifizz:state", (e) => {
  const state = e.detail; // NotifizzState
  document.title = state.unreadCount > 0
    ? `(${state.unreadCount}) My App`
    : "My App";
});
```

## `NotifizzState`

The state object delivered through `notifizz:state` and via the `getState` callback:

| Property      | Type       | Description                                          |
| ------------- | ---------- | ---------------------------------------------------- |
| `isReady`     | `boolean`  | `true` once the widget has loaded and authenticated. |
| `isOpen`      | `boolean`  | `true` when the dropdown is open.                    |
| `unreadCount` | `number`   | Current unread notification count.                   |
| `lastUpdated` | `number`   | Timestamp (ms) of the last state change.             |
| `hasError`    | `boolean?` | `true` if the widget hit an auth or network error.   |
| `errorCode`   | `string?`  | Error identifier when `hasError` is `true`.          |

The first four (`STATE_FIELDS` in the contract) are always present; `hasError` and `errorCode` appear only when the widget enters an error state.

## Lifecycle ordering

A typical session flows like this:

```mermaid theme={null}
sequenceDiagram
    participant Page as Page script
    participant Widget as Notifizz widget

    Page->>Widget: importScriptInBrowser(...)
    Widget-->>Page: window.notifizz available
    Page->>Widget: notifizz("authenticateWith...")
    Widget-->>Page: notifizz:ready (window event)
    Widget-->>Page: notifizz:state { isReady: true, ... }
    Page->>Widget: notifizz("toggle")
    Widget-->>Page: notifizz:state { isOpen: true, ... }
```

<Tip>
  Always wait for `notifizz:ready` (or check `state.isReady`) before sending commands like `toggle` / `open` / `close`. Commands sent before ready are dropped silently — the React/Angular/Vanilla SDKs already gate on this; if you build your own integration, do the same.
</Tip>

## Building your own integration

If you need a framework Notifizz doesn't ship a SDK for (Vue 3 with composables, Solid, Svelte 5, …), the bridge is enough. Minimal recipe:

1. Inject the widget script (`https://widget.notifizz.com/v1/widget.js`) — use a `<script>` tag or your framework's lifecycle hook.
2. Wait until `typeof window.notifizz === "function"`.
3. Call `window.notifizz("authenticateWith…", options)` with your auth fields.
4. Listen for `notifizz:ready` to know when the widget is live.
5. Listen for `notifizz:state` to drive any UI you build around the widget.
6. Call `window.notifizz("toggle" | "open" | "close")` from your own UI elements.

The vanilla SDK (sdk/front-end/notifizz-vanilla) is a clean reference implementation — about 200 lines of glue around this exact protocol.

## FAQ

<AccordionGroup>
  <Accordion title="Open the panel from a button — how?">
    Call `window.notifizz("toggle")` (or `"open"`) from your click handler. If you're using a framework SDK, prefer its idiomatic API (`useNotifizz().toggle` in React, `NotifizzService.toggle()` in Angular, `notifizz.toggle()` in Vanilla) — they all delegate to the same bridge command.
  </Accordion>

  <Accordion title="Read unread count without rendering the default bell.">
    Listen for `notifizz:state` and read `state.unreadCount`. Hide the default bell with CSS or by passing a custom render in your SDK (`renderBell` in React, `#customBellIcon` in Angular, `setBellElement(el)` in Vanilla).
  </Accordion>

  <Accordion title="`getState` returns `isReady: false` immediately after script load.">
    Expected — authentication is async. Call `getState` from inside `notifizz:ready`, or wait for the first `notifizz:state` event whose `detail.isReady === true`.
  </Accordion>

  <Accordion title="Command before `notifizz:ready` — what happens?">
    Dropped silently. The widget queues `authenticateWith…` calls but not `toggle` / `open` / `close`. Always gate your commands on `state.isReady` to avoid surprises.
  </Accordion>

  <Accordion title="Are `setBellIcon` and `setRoundedButton` supported?">
    No — those are internal commands used by the SDK packages and not part of `BRIDGE_COMMANDS`. They may change without notice. If you need a custom bell, use the `renderBell` (React), content-projection (Angular), or `setBellElement(el)` (Vanilla) APIs — those go through the supported public surface.
  </Accordion>

  <Accordion title="Multiple widgets on the same page — supported?">
    No, the widget is a singleton bound to `window.notifizz`. To switch users, destroy the current instance (via your SDK's `destroy()` method) and re-mount with new auth. Two simultaneous identities aren't supported today.
  </Accordion>
</AccordionGroup>

## See also

<CardGroup cols={2}>
  <Card title="Notification Center overview" icon="bell" href="/docs/sdks/notification-center/overview">
    Lifecycle, state model, custom bell, headless mode.
  </Card>

  <Card title="React SDK" icon="react" href="/docs/sdks/notification-center/react">
    Idiomatic React wrapper around the bridge.
  </Card>

  <Card title="Vanilla JS SDK" icon="js" href="/docs/sdks/notification-center/vanilla-js">
    Reference implementation of a bridge consumer.
  </Card>

  <Card title="Authentication overview" icon="key" href="/docs/sdks/authentication/overview">
    The four widget auth modes and when to pick each.
  </Card>
</CardGroup>
