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

> Angular reference for @notifizz/angular — standalone NotifizzAngularComponent, NotifizzService injectable, RxJS state stream, custom bell.

# `@notifizz/angular` SDK reference

`@notifizz/angular` ships a standalone Angular component (`<notifizz-bell>`) and an injectable `NotifizzService` exposing the widget state as an RxJS observable. Use it from any Angular 17+ app.

## TL;DR

* `<notifizz-bell [options]="..." />` — drop-in standalone component that renders the bell + dropdown.
* `NotifizzService` — inject anywhere for programmatic control (`open()`, `close()`, `toggle()`, `state$`).
* Three auth modes via `authType`: `'firebase'`, `'backendToken'`, `'none'` (dev-only).
* Replace the default bell with content projection (`#customBellIcon`) — works with any Angular template or component.

## Installation

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

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

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

## `NotifizzAngularComponent`

A standalone component that renders the bell icon and the notification center. Use the `notifizz-bell` selector in your template.

### Basic usage

```typescript theme={null}
import { Component } from "@angular/core";
import { NotifizzAngularComponent } from "@notifizz/angular";

@Component({
  selector: "app-root",
  standalone: true,
  imports: [NotifizzAngularComponent],
  template: `
    <notifizz-bell
      [options]="notifizzOptions"
      (ready)="onReady()"
      (stateChange)="onStateChange($event)"
    ></notifizz-bell>
  `,
})
export class AppComponent {
  notifizzOptions = {
    apiKey: "YOUR_FRONT_API_KEY",
    authType: "backendToken" as const,
    token: "TOKEN_FROM_BACKEND",
    userId: "user_42",
    userEmail: "alice@example.com",
    position: "top-right" as const,
  };

  onReady() {
    console.log("widget ready");
  }

  onStateChange(state: any) {
    console.log("unread:", state.unreadCount);
  }
}
```

### Inputs

| Input     | Type              | Required | Default                  | Description                         |
| --------- | ----------------- | -------- | ------------------------ | ----------------------------------- |
| `options` | `NotifizzOptions` | yes      | —                        | Authentication and display options. |
| `mountId` | `string`          | no       | `notifizz-notifications` | DOM id for the widget mount point.  |

### Outputs

| Output        | Type                          | Description                            |
| ------------- | ----------------------------- | -------------------------------------- |
| `ready`       | `EventEmitter<void>`          | Emitted once when the widget is ready. |
| `stateChange` | `EventEmitter<NotifizzState>` | Emitted on every state change.         |

### Reactive state

The component exposes a `state$` observable:

```typescript theme={null}
@ViewChild(NotifizzAngularComponent) notifizzComponent!: NotifizzAngularComponent;

ngAfterViewInit() {
  this.notifizzComponent.state$.subscribe((state) => {
    console.log("unread:", state.unreadCount);
  });
}
```

## `NotifizzOptions`

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

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

```typescript theme={null}
notifizzOptions = {
  apiKey: "YOUR_FRONT_API_KEY",
  authType: "none" as const,
  userId: "dev_user_42",
  userEmail: "dev@example.com",
};
```

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

## Custom bell icon

Replace the default bell using Angular content projection. Use the `#customBellIcon` template reference:

```html theme={null}
<notifizz-bell [options]="notifizzOptions">
  <svg
    #customBellIcon
    xmlns="http://www.w3.org/2000/svg"
    width="24"
    height="24"
    fill="none"
    stroke="currentColor"
    stroke-width="2"
    stroke-linecap="round"
    stroke-linejoin="round"
  >
    <path d="M18 8a6 6 0 0 0-12 0c0 7-3 9-3 9h18s-3-2-3-9"></path>
    <path d="M13.73 21a2 2 0 0 1-3.46 0"></path>
  </svg>
</notifizz-bell>
```

You can use any HTML element or Angular component — just add the `#customBellIcon` reference.

## `NotifizzService`

An injectable service for programmatic control of the widget from anywhere in your application — outside the template.

```typescript theme={null}
import { Component } from "@angular/core";
import { NotifizzService } from "@notifizz/angular";

@Component({
  selector: "app-header",
  template: `
    <button (click)="notifizz.toggle()">
      Notifications ({{ (notifizz.state$ | async)?.unreadCount }})
    </button>
  `,
})
export class HeaderComponent {
  constructor(public notifizz: NotifizzService) {}
}
```

### Properties

| Property      | Type                        | Description                                                   |
| ------------- | --------------------------- | ------------------------------------------------------------- |
| `state$`      | `Observable<NotifizzState>` | RxJS observable of the widget state.                          |
| `isReady`     | `boolean`                   | Getter — `true` once the widget has loaded and authenticated. |
| `isOpen`      | `boolean`                   | Getter — `true` when the dropdown is open.                    |
| `unreadCount` | `number`                    | Getter — current unread count.                                |

### Methods

| Method                    | Returns         | Description                                                  |
| ------------------------- | --------------- | ------------------------------------------------------------ |
| `init(options, mountId?)` | `void`          | Initialise the widget programmatically (skip the component). |
| `getState()`              | `NotifizzState` | Synchronous snapshot of the current state.                   |
| `open()`                  | `void`          | Open the notification center.                                |
| `close()`                 | `void`          | Close the notification center.                               |
| `toggle()`                | `void`          | Toggle the notification center.                              |
| `onReady(cb)`             | `() => void`    | Register a ready callback. Returns unsubscribe.              |
| `onStateChange(cb)`       | `() => void`    | Register a state change callback. Returns unsubscribe.       |
| `destroy()`               | `void`          | Clean up the widget and all listeners.                       |

### Programmatic initialisation

Skip the component and drive the widget purely via the service:

```typescript theme={null}
@Component({
  selector: "app-root",
  template: `<div id="notifizz-mount"></div>`,
})
export class AppComponent implements OnInit, OnDestroy {
  constructor(private notifizz: NotifizzService) {}

  ngOnInit() {
    this.notifizz.init(
      {
        apiKey: "YOUR_FRONT_API_KEY",
        authType: "backendToken",
        token: "TOKEN_FROM_BACKEND",
        userId: "user_42",
        userEmail: "alice@example.com",
      },
      "notifizz-mount",
    );
  }

  ngOnDestroy() {
    this.notifizz.destroy();
  }
}
```

## Internal services

<Note>
  These services are used internally by `NotifizzService`. You typically don't need them unless you're building advanced integrations or custom state management.
</Note>

### `NotifizzStateService`

Manages the internal state. Useful if you need fine-grained control over state updates.

| Property/Method                      | Type                        | Description                         |
| ------------------------------------ | --------------------------- | ----------------------------------- |
| `state$`                             | `Observable<NotifizzState>` | State observable (BehaviorSubject). |
| `isReady` / `isOpen` / `unreadCount` | getters                     | Convenience accessors.              |
| `getState()`                         | `NotifizzState`             | Synchronous snapshot.               |
| `onReady(cb)`                        | `() => void`                | Register a ready callback.          |
| `onStateChange(cb)`                  | `() => void`                | Register a state change callback.   |
| `destroy()`                          | `void`                      | Clean up subscriptions.             |

### `NotifizzCommandService`

Sends commands to the widget. Used internally by `NotifizzService`.

| Method                            | Description                                         |
| --------------------------------- | --------------------------------------------------- |
| `open()` / `close()` / `toggle()` | Drive the dropdown.                                 |
| `send(command, ...args)`          | Send an arbitrary command to the underlying widget. |

## State shape

`NotifizzState` (delivered through `state$`, `onStateChange`, the `stateChange` output):

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

## Exported types

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

## FAQ

<AccordionGroup>
  <Accordion title="Does this work with Angular's NgModule-based app structure?">
    `NotifizzAngularComponent` is standalone but importable into any module via `imports: [NotifizzAngularComponent]`. The same applies if you migrate part of an existing NgModule app to standalone. The `NotifizzService` is provided in `'root'` and works in both setups.
  </Accordion>

  <Accordion title="Server-side rendering — what happens?">
    The widget is browser-only. On the server, `NotifizzAngularComponent` renders an empty mount `<div>` and the service no-ops. Hydration on the client triggers script loading and authentication. SSR works without extra config.
  </Accordion>

  <Accordion title="Multiple components show different states.">
    They shouldn't — `NotifizzService` is provided in `'root'`, so every injection sees the same `state$` BehaviorSubject. If you see drift, you have probably re-provided the service at the component level (`providers: [NotifizzService]`), creating a separate instance. Remove the local provider.
  </Accordion>

  <Accordion title="`stateChange` fires before `ready`. Is that expected?">
    Yes. The widget can publish a state update for the cached `getState` result before the `ready` event fires (e.g. `unreadCount` from the previous session). Always gate UI on `state.isReady === true` if you need post-auth state.
  </Accordion>

  <Accordion title="How do I switch user without recreating the component?">
    Update `notifizzOptions.userId` / `notifizzOptions.token` and call `notifizz.destroy()` then `notifizz.init(...)` from the service. The component does not currently re-authenticate on `[options]` change in place — destroy + re-init is the safe path.
  </Accordion>

  <Accordion title="Custom bell click does not toggle the dropdown.">
    Make sure the projected element has the `#customBellIcon` template reference variable. The component listens for clicks on the element matching that reference; without it, your icon renders but the click handler never wires up.
  </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>
