> ## 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 Frontend Quickstart

> Embed the Notifizz Notification Center widget in React, Angular, or vanilla JS in under five minutes.

# Notifizz frontend quickstart

Embed the Notification Center widget in your app. Pick the SDK that matches your stack — they wrap the same widget and expose the same options.

## TL;DR

* Install `@notifizz/react`, `@notifizz/angular`, or `@notifizz/vanilla`.
* Pass `apiKey` (Front API Key) + an auth mode (`firebase`, `backendToken`, or `none` for dev).
* The bell renders in the position you configure; updates stream in real-time — no polling.

<Info>
  Get your **Front API Key** from the [Notifizz dashboard](https://notifizz.com). If you use `backendToken` mode, your backend also needs to call `client.generateHashedToken(userId)` and ship the result to the frontend ([backend quickstart](/docs/quickstart/backend) covers that step).
</Info>

## Choose your framework

<Tabs>
  <Tab title="React">
    ### 1. Install

    ```bash theme={null}
    npm install @notifizz/react
    ```

    ### 2. Render the inbox

    ```jsx theme={null}
    import NotifizzInbox from "@notifizz/react";

    function App() {
      return (
        <div>
          <NotifizzInbox
            options={{
              apiKey: "YOUR_FRONT_API_KEY",
              authType: "backendToken",
              token: "TOKEN_FROM_YOUR_BACKEND",
              userId: "user_42",
              userEmail: "alice@example.com",
              position: "top-right",
            }}
            onReady={() => console.log("widget ready")}
          />
          {/* your app */}
        </div>
      );
    }
    ```

    A bell icon appears in the configured position. Click it to open the Notification Center.

    ### 3. (Optional) Provider for app-wide state

    ```jsx theme={null}
    import { NotifizzProvider, useNotifizz } from "@notifizz/react";

    function App() {
      return (
        <NotifizzProvider
          options={{
            apiKey: "YOUR_FRONT_API_KEY",
            authType: "backendToken",
            token: "TOKEN_FROM_YOUR_BACKEND",
            userId: "user_42",
            userEmail: "alice@example.com",
          }}
        >
          <Header />
          <MainContent />
        </NotifizzProvider>
      );
    }

    function Header() {
      const { unreadCount, toggle } = useNotifizz();
      return (
        <button onClick={toggle}>Notifications ({unreadCount})</button>
      );
    }
    ```
  </Tab>

  <Tab title="Angular">
    ### 1. Install

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

    ### 2. Mount the standalone component

    ```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]="{
            apiKey: 'YOUR_FRONT_API_KEY',
            authType: 'backendToken',
            token: 'TOKEN_FROM_YOUR_BACKEND',
            userId: 'user_42',
            userEmail: 'alice@example.com',
            position: 'top-right'
          }"
          (ready)="onReady()"
        ></notifizz-bell>
      `,
    })
    export class AppComponent {
      onReady() {
        console.log("widget ready");
      }
    }
    ```
  </Tab>

  <Tab title="Vanilla JS">
    ### 1. Install

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

    ### 2. Create and mount the widget

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

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

    notifizz.mount();
    notifizz.onReady(() => console.log("widget ready"));
    ```

    ### Via script tag (no bundler)

    ```html theme={null}
    <div id="notifizz-notifications"></div>

    <script type="module">
      import { createNotifizz } from "https://cdn.jsdelivr.net/npm/@notifizz/vanilla/+esm";

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

      notifizz.mount(document.getElementById("notifizz-notifications"));
    </script>
    ```

    <Warning>
      `authType: "none"` ships unauthenticated widget access — anyone with the API key can read any user's inbox. Use it for local development only.
    </Warning>
  </Tab>
</Tabs>

<Tip>
  **Going beyond the bell?** [Notifizz Certified Partners](/docs/partners/certified-partners) lead complete notification programmes — events wired in your backend, enrichers fetching live profile data, AI/MCP set up to author campaigns, brand and templates ready, team trained. The fastest way to ship a measurable programme. **[Find a partner →](/docs/partners/certified-partners)**
</Tip>

## Verify

<Steps>
  <Step title="Backend ready">
    Your backend tracks events ([backend quickstart](/docs/quickstart/backend)).
  </Step>

  <Step title="Bell visible">
    Open your app — the bell icon appears in the configured position.
  </Step>

  <Step title="Trigger an event">
    Send an event from your backend whose recipient resolves to the same `userId` you passed to the widget.
  </Step>

  <Step title="Notification received">
    The bell badge updates and the notification appears in the dropdown — real-time, no refresh.
  </Step>
</Steps>

## FAQ

<AccordionGroup>
  <Accordion title="The bell renders but the badge stays at 0.">
    The widget is connected, but no message has been delivered to this `userId` yet. Check three things: (1) the campaign in the dashboard is `Live` (or `Dev` on dev environments); (2) the event you fired resolves to the same `userId` you passed to the widget; (3) check the dashboard delivery history — if the message shipped server-side but doesn't appear, the auth identity probably mismatches.
  </Accordion>

  <Accordion title="`isReady` never flips to `true`.">
    Auth failed. Check the browser console — the widget logs the auth error. Common causes: stale `token`, wrong `authType`, expired Front API Key. Inspect `state.hasError` / `state.errorCode` for a typed signal.
  </Accordion>

  <Accordion title="`backendToken` vs `firebase` — how do I pick?">
    If your app already uses Firebase Auth, use `firebase` — zero backend changes. Otherwise use `backendToken`, generated server-side via `client.generateHashedToken(userId)` from your Notifizz Node SDK. See [authentication overview](/docs/sdks/authentication/overview).
  </Accordion>

  <Accordion title="Can I render the bell only after the user logs in?">
    Yes — render `NotifizzInbox` (or the Angular component / vanilla mount) only when the user is authenticated and you have the token. The widget needs `userId` + `token` upfront; mounting it before login wastes a script load.
  </Accordion>

  <Accordion title="Multiple users on the same browser — how do I switch?">
    Destroy the current widget and remount with the new identity. React: conditionally render the provider on `userId`. Angular: call `notifizz.destroy()` then `notifizz.init(...)` from `NotifizzService`. Vanilla: `notifizz.destroy()` then `createNotifizz(...)` again.
  </Accordion>

  <Accordion title="My site has a strict Content-Security-Policy — what do I need to allow?">
    The widget shares one real-time stream across every tab of your site by spawning a SharedWorker. If your CSP blocks it, the widget falls back transparently to a per-tab connection — no error, just slightly more network. To get the optimised path, allow the widget origin in `worker-src`:

    ```
    Content-Security-Policy: worker-src https://widget.notifizz.com 'self';
    ```

    Embedded WebViews (Instagram, TikTok, LinkedIn) and Safari before 16.4 don't ship SharedWorker. Same fallback applies — nothing to do on your side.
  </Accordion>
</AccordionGroup>

## See also

<CardGroup cols={2}>
  <Card title="Work with a Certified Partner" icon="handshake" href="/docs/partners/certified-partners">
    The fastest path from "we want this" to a running, owned programme.
  </Card>

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

  <Card title="Authentication overview" icon="key" href="/docs/sdks/authentication/overview">
    Firebase, backend token, publicly-signed JWT, or none.
  </Card>

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