WebNotification

Reactive wrapper around the Notifications API. Show browser notifications with Angular signals.

Secure Context Required

This feature is available only in secure contexts (HTTPS) or potentially trustworthy origins (such as localhost or 127.0.0.1). Regular http:// URLs will not work in most browsers.

OS-Level Notification Settings

Even after the browser grants notification permission, the operating system may still block notifications for the browser app. In this case permission() returns 'granted' but no notifications appear — the Notification API provides no way to detect OS-level blocking.

  • macOS — System Settings → Notifications → select your browser → enable "Allow notifications"
  • Windows — Settings → System → Notifications → ensure notifications are enabled globally and for the specific browser. Focus Assist (Do Not Disturb) will also suppress all notifications when active
  • Linux (GNOME) — Settings → Notifications → ensure the browser app is allowed. Do Not Disturb mode suppresses non-critical notifications
  • Linux (KDE Plasma) — System Settings → Notifications → check per-app settings and Do Not Disturb mode

If notifications are not appearing despite permission() being 'granted', check the OS notification settings for your browser first.

Loading demo...

Usage

On supported platforms, showing a system notification requires the user to grant permission via requestPermission(). This method must be called during a user gesture (e.g., click). Permission states: default (not requested), granted, or denied.

angular-ts
import { Component } from '@angular/core';
import { webNotification } from '@signality/core';

@Component({
  template: `
    @if (notif.isSupported()) {
      @if (notif.permission() === 'default') { 
        <button (click)="requestPermission()">
          Enable Notifications
        </button>
      } @else if (notif.notification() === 'granted') {
        <button (click)="showNotification()">
          Show Notification
        </button>
      }
    }
  `,
})
export class NotificationDemo {
  readonly notif = webNotification(); 
  
  async requestPermission() {
    await this.notif.requestPermission();
  }
  
  showNotification() {
    this.notif.show('Hello!', {
      body: 'This is a notification from Signality',
    });
  }
}

Parameters

ParameterTypeDescription
optionsWebNotificationOptionsOptional configuration (see Options below)

Options

Extends standard NotificationOptions — any option set here becomes the default for every show() call.

OptionTypeDefaultDescription
autoCloseMaybeSignal<number>-Auto-close notification after specified milliseconds
injectorInjector-Optional injector for DI context
badgestring-URL of image shown when there isn't enough space to display the notification
bodystring-Default body text
dataany-Arbitrary data to associate with the notification
dir'ltr' | 'rtl' | 'auto''auto'Text direction
iconstring-Default icon URL
imagestring-URL of image to display in the notification
langstring''Language code (BCP 47)
renotifybooleanfalseNotify when replacing an existing notification
requireInteractionbooleanfalseKeep notification visible until user interacts
silentbooleanfalseSuppress sound and vibration
tagstring-Default tag for replacing notifications
timestampnumber-Timestamp (Unix time in milliseconds)
vibratenumber[]-Vibration pattern for device vibration hardware

Return Value

The webNotification() function returns a WebNotificationRef object:

PropertyTypeDescription
isSupportedSignal<boolean>Whether Notifications API is supported
permissionSignal<NotificationPermission>Current permission state
notificationSignal<Notification | null>Current active notification instance
requestPermission() => Promise<NotificationPermission>Request notification permission
show(title, options?) => Notification | undefinedShow a notification (auto-closes previous)
close() => voidClose the current notification

Examples

Auto-close notification

angular-ts
import { Component, signal } from '@angular/core';
import { webNotification } from '@signality/core';

@Component({
  template: `<button (click)="showTempNotification()">Show Temp</button>`,
})
export class TempNotification {
  readonly notif = webNotification({ autoClose: 5000 }); 
  
  showTempNotification() {
    // Automatically closes after 5 seconds
    this.notif.show('Quick update', {
      body: 'This will disappear in 5 seconds',
    });
  }
}

Browser Compatibility

The Notifications API has limited browser support, especially on mobile devices. Always check isSupported() before using notifications (see Browser API support detection):

angular-html
@if (notification.isSupported()) {
  <button (click)="notification.show('Hello!')">Show Notification</button>
} @else {
  <p>Notifications are not available in this browser</p>
}

For detailed browser support information, see Can I use: Notifications API.

SSR Compatibility

On the server, signals initialize with safe defaults:

  • isSupportedfalse
  • permission'denied'
  • notificationnull
  • requestPermission → returns 'denied'
  • show → returns undefined
  • close → no-op function

Type Definitions

typescript
interface WebNotificationOptions extends NotificationOptions, WithInjector {
  readonly autoClose?: MaybeSignal<number>;
}

interface WebNotificationRef {
  readonly isSupported: Signal<boolean>;
  readonly permission: Signal<NotificationPermission>;
  readonly notification: Signal<Notification | null>;
  readonly requestPermission: () => Promise<NotificationPermission>;
  readonly show: (title: string, options?: NotificationOptions) => Notification | undefined;
  readonly close: () => void;
}

function webNotification(options?: WebNotificationOptions): WebNotificationRef;
Edit this page on GitHub Last updated: Mar 19, 2026, 23:28:23