> ## 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/vanilla SDK Reference

> Framework-agnostic reference for @notifizz/vanilla — createNotifizz, mount, state callbacks, custom bell element, full HTML example.

# `@notifizz/vanilla` SDK reference

`@notifizz/vanilla` is the framework-agnostic SDK for the Notifizz Notification Center widget. Use it from plain JavaScript, Vue, Svelte, server-rendered pages with islands, or any setup that isn't already covered by `@notifizz/react` or `@notifizz/angular`.

## TL;DR

* `createNotifizz(options)` returns a `NotifizzVanillaApi` — call `mount()` to attach the bell to the DOM.
* Three auth modes via `authType`: `'firebase'`, `'backendToken'`, `'none'` (dev-only).
* Subscribe to changes with `onStateChange(cb)`; read state synchronously with `getState()`.
* Replace the default bell with `setBellElement(el)` — the SDK handles click + keeps a `data-unread` attribute in sync.

## Installation

<CodeGroup>
  ```bash npm theme={null}
  npm install @notifizz/vanilla
  ```

  ```bash yarn theme={null}
  yarn add @notifizz/vanilla
  ```

  ```bash pnpm theme={null}
  pnpm add @notifizz/vanilla
  ```
</CodeGroup>

## `createNotifizz(options)`

Creates a new Notifizz instance. This is the entry point for the SDK.

```javascript theme={null}
import { createNotifizz } from "@notifizz/vanilla";

const notifizz = createNotifizz({
  apiKey: "YOUR_FRONT_API_KEY",
  authType: "backendToken",
  token: "TOKEN_FROM_BACKEND",
  userId: "user_42",
  userEmail: "alice@example.com",
  position: "top-right",
});
```

### Options

| Option                     | Type                                            | Required                       | Default                          | Description                          |
| -------------------------- | ----------------------------------------------- | ------------------------------ | -------------------------------- | ------------------------------------ |
| `apiKey`                   | `string`                                        | yes                            | —                                | Your Front API Key.                  |
| `authType`                 | `'firebase' \| 'backendToken' \| 'none'`        | yes                            | —                                | Authentication strategy.             |
| `token`                    | `string`                                        | for `firebase`, `backendToken` | —                                | Auth token from your backend.        |
| `userId`                   | `string`                                        | for `backendToken`, `none`     | —                                | The user's unique identifier.        |
| `userEmail`                | `string`                                        | for `backendToken`, `none`     | —                                | The user's email address.            |
| `position`                 | `NotifizzPosition`                              | no                             | —                                | Bell position.                       |
| `notificationCenterStyles` | `{ marginTop?: string }`                        | no                             | —                                | Notification center style overrides. |
| `bellStyles`               | `{ marginRight?: string; marginLeft?: string }` | no                             | —                                | Bell style overrides.                |
| `serverUrl`                | `string`                                        | no                             | `https://widget.notifizz.com`    | Widget server URL.                   |
| `apiUrl`                   | `string`                                        | no                             | `https://eu.api.notifizz.com/v1` | API base URL.                        |
| `widgetPath`               | `string`                                        | no                             | `/v1/widget.js`                  | Widget script path.                  |
| `mountId`                  | `string`                                        | no                             | `notifizz-notifications`         | DOM id for the mount point.          |

**Returns** — `NotifizzVanillaApi`, the instance API described below.

### `authType: "none"` example (dev only)

```javascript theme={null}
const notifizz = createNotifizz({
  apiKey: "YOUR_FRONT_API_KEY",
  authType: "none",
  userId: "dev_user_42",
  userEmail: "dev@example.com",
});

notifizz.mount();
```

<Warning>
  `authType: "none"` ships unauthenticated widget access — anyone with the `apiKey` can read any user's inbox. Use it for local development only. Production must use `firebase` or `backendToken`.
</Warning>

## Instance methods

### `mount(element?)`

Mounts the widget to the DOM. If no element is provided, creates a `<div>` and appends it to `document.body`.

```javascript theme={null}
// Auto-mount to body
notifizz.mount();

// Mount to a specific element
const container = document.getElementById("my-notifications");
notifizz.mount(container);
```

| Parameter | Type          | Required | Description                                           |
| --------- | ------------- | -------- | ----------------------------------------------------- |
| `element` | `HTMLElement` | no       | Target DOM element. Created automatically if omitted. |

**Returns** — `HTMLElement`, the mounted element.

### `getState()`

Synchronous snapshot of the current widget state.

```javascript theme={null}
const state = notifizz.getState();
console.log(state.unreadCount); // 3
console.log(state.isOpen);      // false
```

**Returns** — `NotifizzState`:

| 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 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`.          |

### `onReady(callback)`

Registers a callback that fires when the widget is ready. If the widget is already ready, the callback fires immediately.

```javascript theme={null}
const unsubscribe = notifizz.onReady(() => {
  console.log("widget ready");
});

unsubscribe(); // stop listening
```

**Returns** — `() => void`, an unsubscribe function.

### `onStateChange(callback)`

Registers a callback that fires on every state change.

```javascript theme={null}
const unsubscribe = notifizz.onStateChange((state) => {
  document.title = state.unreadCount > 0
    ? `(${state.unreadCount}) My App`
    : "My App";
});
```

**Returns** — `() => void`, an unsubscribe function.

### `onBellUpdate(callback)`

Registers a callback that fires when the bell context updates (unread count, open state).

```javascript theme={null}
const unsubscribe = notifizz.onBellUpdate((ctx) => {
  console.log("unread:", ctx.unreadCount);
  console.log("isOpen:", ctx.isOpen);
});
```

The callback receives a `NotifizzBellContext`:

| Property      | Type         | Description                   |
| ------------- | ------------ | ----------------------------- |
| `unreadCount` | `number`     | Current unread count.         |
| `isOpen`      | `boolean`    | Whether the dropdown is open. |
| `isReady`     | `boolean`    | Whether the widget is ready.  |
| `toggle`      | `() => void` | Toggle the dropdown.          |
| `open`        | `() => void` | Open the dropdown.            |
| `close`       | `() => void` | Close the dropdown.           |

**Returns** — `() => void`, an unsubscribe function.

### `open()` / `close()` / `toggle()`

Drive the dropdown programmatically.

```javascript theme={null}
notifizz.open();
notifizz.close();
notifizz.toggle();
```

### `setBellElement(element)`

Sets a custom HTML element as the bell. The SDK adds a click listener that toggles the dropdown and keeps a `data-unread` attribute in sync with the current count.

```javascript theme={null}
const myBell = document.getElementById("my-bell");
notifizz.setBellElement(myBell);
```

```html theme={null}
<button id="my-bell">
  Notifications <span class="badge"></span>
</button>

<style>
  /* Style based on the data-unread attribute */
  #my-bell[data-unread="0"] .badge { display: none; }
  #my-bell .badge::after { content: attr(data-unread); }
</style>
```

| Parameter | Type                  | Description                                     |
| --------- | --------------------- | ----------------------------------------------- |
| `element` | `HTMLElement \| null` | The custom bell element. Pass `null` to remove. |

### `destroy()`

Removes the widget from the DOM and cleans up all event listeners.

<Warning>
  `destroy()` is one-way — you cannot reuse the instance afterwards. Call `createNotifizz(...)` again for a fresh instance.
</Warning>

```javascript theme={null}
notifizz.destroy();
```

## Full example

```html theme={null}
<!DOCTYPE html>
<html>
<head>
  <title>Notifizz Vanilla example</title>
</head>
<body>
  <header>
    <h1>My App</h1>
    <button id="notif-bell">Notifications</button>
  </header>

  <script type="module">
    import { createNotifizz } from "@notifizz/vanilla";

    const notifizz = createNotifizz({
      apiKey: "YOUR_FRONT_API_KEY",
      authType: "backendToken",
      token: "TOKEN_FROM_BACKEND",
      userId: "user_42",
      userEmail: "alice@example.com",
    });

    notifizz.mount();

    const bell = document.getElementById("notif-bell");
    notifizz.setBellElement(bell);

    notifizz.onStateChange((state) => {
      document.title = state.unreadCount > 0
        ? `(${state.unreadCount}) My App`
        : "My App";
    });
  </script>
</body>
</html>
```

## Exported types

```typescript theme={null}
import type {
  NotifizzState,
  NotifizzPosition,
  NotifizzBellContext,
  NotifizzOptions,
  NotifizzVanillaApi,
} from "@notifizz/vanilla";
```

## FAQ

<AccordionGroup>
  <Accordion title="Can I use this SDK from Vue / Svelte / Solid / etc?">
    Yes — the vanilla SDK is framework-agnostic by design. Mount the widget in the framework's lifecycle hook (`onMounted`, `onMount`, `useEffect`-equivalent) and `destroy()` in the teardown. The state callbacks plug into any reactive store.
  </Accordion>

  <Accordion title="The widget mounted but the bell is not visible.">
    Three things to check: (1) `mount()` was called and returned a non-null element; (2) the page hasn't hidden the mount point with global CSS (`#notifizz-notifications { display: none }`); (3) `state.isReady === true` — the bell renders only after auth succeeds, and a failure flips `hasError` instead.
  </Accordion>

  <Accordion title="`getState()` returns `isReady: false` immediately after `createNotifizz`.">
    Expected — `createNotifizz()` doesn't load the script synchronously. Call `mount()` first, then either await `onReady()` or check `state.isReady` in `onStateChange`.
  </Accordion>

  <Accordion title="My custom bell click does nothing.">
    `setBellElement(el)` overrides the default bell. If you registered your own click handler before calling it, the SDK still adds *its* listener — but your handler may stop the event with `preventDefault` / `stopPropagation`. Either rely on the SDK's click handler, or attach yours after `setBellElement` and don't stop propagation.
  </Accordion>

  <Accordion title="Where do `onStateChange` callbacks get called from?">
    The widget posts state changes via the `notifizz:state` window event. The SDK subscribes to that event once and fans out to your callbacks — there is no polling. State changes happen on the client, off the real-time stream listener.
  </Accordion>

  <Accordion title="How do I switch user?">
    Call `destroy()` on the current instance, then `createNotifizz(...)` with the new `userId` + `token`, then `mount()`. The widget caches real-time state per session, so without `destroy` the new mount briefly shows the previous user's notifications.
  </Accordion>
</AccordionGroup>

## See also

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

  <Card title="Authentication overview" icon="key" href="/docs/sdks/authentication/overview">
    Pick the right widget auth mode.
  </Card>

  <Card title="Frontend quickstart" icon="rocket" href="/docs/quickstart/frontend">
    Get the widget rendering in under five minutes.
  </Card>

  <Card title="Backend quickstart" icon="satellite-dish" href="/docs/quickstart/backend">
    Send the events the widget will display.
  </Card>
</CardGroup>
