Notifications API

Living Standard — Last Updated 20 August 2014

This Version:
http://notifications.spec.whatwg.org/
Participate:
Send feedback to whatwg@whatwg.org or file an issue (open issues)
IRC: #whatwg on Freenode
Version History:
https://github.com/whatwg/notifications/commits
Editor:
Anne van Kesteren (Mozilla) <annevk@annevk.nl>
Former editor:
John Gregg (Google) <johnnyg@google.com>

Table of contents

  1. 1 Introduction
  2. 2 Conformance
    1. 2.1 Security
  3. 3 Terminology
  4. 4 Model
    1. 4.1 Direction
    2. 4.2 Language
    3. 4.3 Permission
    4. 4.4 Notification lists
    5. 4.5 Showing a notification
    6. 4.6 Activating a notification
    7. 4.7 Closing a notification
    8. 4.8 Pending notifications
    9. 4.9 Displaying notifications
    10. 4.10 Replacing a notification
  5. 5 API
    1. 5.1 Garbage collection
    2. 5.2 Constructors
    3. 5.3 Static members
    4. 5.4 Object members
  6. 6 Examples
    1. 6.1 Using events
    2. 6.2 Using the tag member for multiple instances
    3. 6.3 Using the tag member for a single instance
  7. References
  8. Acknowledgments

1 Introduction

This specification provides an API to display notifications to alert end users outside the context of a browsing context's viewport. It does not specify in detail how a user agent is to display these notifications; the best presentation depends on the output device.

This specification is designed to be compatible with existing notification platforms, while remaining platform-independent. In general, this specification is best-effort; e.g. while notifications can be activated, the underlying notification platform could not support that and so it cannot be relied upon.

2 Conformance

All diagrams, examples, and notes in this specification are non-normative, as are all sections explicitly marked non-normative. Everything else in this specification is normative.

The key words "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in the normative parts of this specification are to be interpreted as described in RFC2119. For readability, these words do not appear in all uppercase letters in this specification. [RFC2119]

2.1 Security

Notifications should only be presented when the user has indicated they are desired; without this they could create a negative experience for the user.

3 Terminology

Most terminology used in this specification is from DOM, Fetch HTML, IDL, and URL. [DOM] [FETCH] [HTML] [WEBIDL] [URL]

4 Model

A notification allows alerting the end user outside a browsing context's viewport of an occurrence, such as the delivery of email.

Each notification has a title, body, direction, language, tag, data, and an origin.

Each notification can have an associated icon URL and icon image.

4.1 Direction

This section is written in terms equivalent to those used in the Rendering section of HTML. [HTML]

User agents are expected to honor the Unicode semantics of the text of a notification's title and body. Each is expected to be treated as an independent set of one or more bidirectional algorithm paragraphs when displayed, as defined by the bidirectional algorithm's rules P1, P2, and P3, including, for instance, supporting the paragraph-breaking behaviour of U+000A LINE FEED (LF) characters. For each paragraph of the title and body, the notification's direction provides the higher-level override of rules P2 and P3 if it has a value other than "auto". [BIDI]

4.2 Language

The notification's language specifies the primary language for the notification's title and body. Its value is a valid BCP 47 language tag, or the empty string. The empty string indicates that the primary language is unknown. [LANG]

4.3 Permission

Notifications can only be displayed if the user (or user agent on behalf of the user) has granted permission. The permission to display notifications for a given origin can be one of three strings:

"default"

This is equivalent to "denied", but the user has made no explicit choice thus far.

"denied"

This means the user does not want notifications.

"granted"

This means notifications can be displayed.

There is no equivalent to "default" meaning "granted". In that case "granted" is simply returned as there would be no reason for the application to ask for permission.

4.4 Notification lists

The user agent must keep a list of pending notifications and a list of active notifications.

4.5 Showing a notification

The show steps for a given notification are:

  1. If permission for notification's origin is not "granted", terminate any ongoing fetch for notification's icon URL, then for each Notification object representing notification, queue a task to fire an event named error on the Notification object, and terminate these steps.

  2. If there is a notification in the list of pending notifications or the list of active notifications whose tag is not the empty string and equals notification's tag, and whose origin equals notification's origin, run the replace steps for that notification and notification, and then terminate these steps.

  3. If the device allows notifications to be displayed immediately without limitations on the number of concurrent notifications, run the display steps for notification and terminate these steps.

  4. If the device has limitations on the number of concurrent notifications, either immediately call to a notification platform which natively supports queueing, or append notification to the list of pending notifications.

4.6 Activating a notification

When a notification notification is activated by the user, assuming the underlying notification platform supports activation, the user agent must, for each Notification object representing notification, queue a task to fire an event named click on the Notification object.

Throughout the web platform "activate" is intentionally misnamed as "click".

User agents are strongly encouraged to make window.focus() work from within the event listener for the event named click as a means of focusing the browsing context related to the notification.

4.7 Closing a notification

When a notification is closed, either by the underlying notification platform or by the user, the close steps for it must be run.

The close steps for a given notification are:

  1. If notification is neither in the list of pending notifications nor in the list of active notifications, terminate these steps.

  2. Remove notification from either the list of pending notifications or the list of active notifications, and then for each Notification object representing notification, queue a task to fire an event named close on the Notification object.

4.8 Pending notifications

Whenever the list of pending notifications is not empty, the user agent must wait and monitor changes in the available notification space on the device.

When the available display space changes on the device such that a new notification can be displayed, for example due to a previous notification being dismissed, the user agent should run the display steps for the first notification in the list of pending notifications and then remove it from the list of pending notifications.

4.9 Displaying notifications

The display steps for a given notification are:

  1. If the notification platform supports icons, notification's icon URL is set and has not yet been fetched, fetch it and wait for the response.

    If the response's internal response's type is default, attempt to decode the resource as image.

    Once fetching has finished and the image format is supported, set notification's icon image to the decoded resource. (Otherwise notification has no icon image.)

  2. Display notification on the device (e.g. by calling the appropriate notification platform).

  3. If displaying fails (e.g. the notification platform returns an error), for each Notification object representing notification, queue a task to fire an event named error on the Notification object and terminate these steps.

  4. Append notification to the list of active notifications.

  5. For each Notification object representing notification, queue a task to fire an event named show on the Notification object.

4.10 Replacing a notification

The replace steps for replacing an old notification with a new one are:

  1. If the notification platform supports icons, new's icon URL is set and has not yet been fetched, fetch it and wait for the response.

    If the response's internal response's type is default, attempt to decode the resource as image.

    Once fetching has finished and the image format is supported, set new's icon image to the decoded resource. (Otherwise new has no icon image.)

  2. If old is in the list of pending notifications, replace old with new, in the same position, in the list of pending notifications, and then for each Notification object representing old, queue a task to fire an event named close on the Notification object.

  3. Otherwise, replace old with new, in the same position, in the list of active notifications, then for each Notification object representing old, queue a task to fire an event named close on the Notification object, and then for each Notification object representing new, queue a task to fire an event named show on the Notification object.

    If the notification platform does not support replacement this requirement may be addressed by running the close steps for old and then running the display steps for new.

    Notification platforms are strongly encouraged to support native replacement. It is much nicer.

5 API

A notification is represented by zero or more Notification objects and can be created by Notification's constructor.

[Constructor(DOMString title, optional NotificationOptions options),
 Exposed=(Window,Worker)]
interface Notification : EventTarget {
  static readonly attribute NotificationPermission permission;
  [Exposed=Window] static void requestPermission(optional NotificationPermissionCallback callback);

  static Promise<sequence<Notification>> get(optional GetNotificationOptions filter);

  attribute EventHandler onclick;
  attribute EventHandler onshow;
  attribute EventHandler onerror;
  attribute EventHandler onclose;

  readonly attribute DOMString title;
  readonly attribute NotificationDirection dir;
  readonly attribute DOMString lang;
  readonly attribute DOMString body;
  readonly attribute DOMString tag;
  readonly attribute DOMString icon;
  [SameObject] readonly attribute any data;

  void close();
};

dictionary NotificationOptions {
  NotificationDirection dir = "auto";
  DOMString lang = "";
  DOMString body = "";
  DOMString tag = "";
  DOMString icon;
  any data = null;
};

dictionary GetNotificationOptions {
  DOMString tag = "";
};

enum NotificationPermission {
  "default",
  "denied",
  "granted"
};

callback NotificationPermissionCallback = void (NotificationPermission permission);

enum NotificationDirection {
  "auto",
  "ltr",
  "rtl"
};

5.1 Garbage collection

A Notification object must not be garbage collected while its corresponding notification is in either the list of pending notifications or in the list of active notifications and the Notification object in question has an event listener whose type is click, show, error or close.

5.2 Constructors

The Notification(title, options) constructor must run these steps:

  1. Let notification be a new notification represented by a Notification object.

  2. Set notification's title to title.

  3. Set notification's direction to options's dir.

  4. If options's lang is a valid BCP 47 language tag, or the empty string, set notification's language to options's lang, or set it to the empty string otherwise. [LANG]

  5. Set notifications's origin to the entry settings object's origin.

  6. Set notification's body to options's body.

  7. Set notification's tag to options's tag.

  8. If options's icon is present, parse icon using the API base URL specified by the entry settings object, and if that does not return failure, set notification's icon URL to the return value. (Otherwise icon URL is not set.)

  9. Set notification's data to a structured clone of options's data. Re-throw any exception.

  10. Return notification, but continue running these steps asynchronouusly.

  11. If the notification platform supports icons, the user agent may start fetching notification's icon URL at this point, if icon URL is set.

  12. Run the show steps for notification.

5.3 Static members

The static permission attribute must return permission.

The static requestPermission(callback) method must run these steps:

  1. Return, but continue running these steps asynchronously.

  2. Let permission be permission.

  3. If permission is "default", ask the user whether showing notifications for the entry settings object's origin is acceptable. If it is, set permission to "granted", and "denied" otherwise.

  4. Queue a task to set permission to permission and invoke callback with permission as single argument if callback is given.

In designing the platform notifications are the one instance thus far where asking the user upfront makes sense. Specifications for other APIs should not use this pattern and instead employ one of the many more suitable alternatives.

The static get(filter) method must run these steps:

  1. Let promise be a new promise.

  2. Return promise and continue running the remaining steps asynchronously.

  3. Let tag be filter's tag.

  4. Let notifications be a list of all notifications in either the list of pending notifications or in the list of active notifications whose origin is the entry settings object's origin and whose tag, if tag is not the empty string, is tag.

  5. Let objects be an empty JavaScript array.

  6. For each notification in notifications, in creation order, create a new Notification object representing notification and push that object to objects.

  7. Resolve promise with objects.

This method returns zero or more new Notification objects which might represent the same underlying notification of Notification objects already in existence.

5.4 Object members

The following are the event handlers (and their corresponding event handler event types) that must be supported as attributes by the Notification object.

event handler event handler event type
onclick click
onshow show
onerror error
onclose close

The close() method must run the close steps for the notification.

The title attribute must return the notification's title.

The dir attribute must return the notification's direction.

The lang attribute must return the notification's language.

The body attribute must return the notification's body.

The tag attribute must return the notification's tag.

The icon attribute must return the notification's icon URL, serialized, and the empty string if there is no notification's icon URL otherwise.

The data attribute must return a structured clone of notification's data.

6 Examples

6.1 Using events

Notification objects dispatch events during their lifecycle, which developers can use to generate desired behaviors.

The show event dispatches when the notification is shown to the user — this may be at some time after the notification is created in the case of limited display space and a queue.

In the following example, this event is used to guarantee that regardless of when the notification is shown, it is displayed for only 15 seconds.

var notification = new Notification("New Email Received", { icon: "mail.png" })
notification.onshow = function() { setTimeout(notification.close, 15000) }

The close event dispatches when the notification is dismissed by the user. Developers may use this event to perform actions when notifications are acknowledged.

In the following example, when a meeting reminder notification is acknowledged, the application suppresses other forms of reminders.

var notification = new Notification("Meeting about to begin", { icon: "calendar.gif", body: "Room 101" })
notification.onclose = function(event) { cancelReminders(event) }

6.2 Using the tag member for multiple instances

Web applications frequently operate concurrently in multiple instances, such as when a user opens a mail application in multiple browser tabs. Since the desktop is a shared resource, the notifications API provides a way for these instances to easily coordinate, by using the tag member.

Notifications which represent the same conceptual event can be tagged in the same way, and when both are shown, the user will only receive one notification.

Instance 1                                   | Instance 2
                                             |
// Instance notices there is new mail.       |
new Notification("New mail from John Doe",   |
                 { tag: 'message1' });       |
                                             |
                                             |  // Slightly later, this instance notices
                                             |  // there is new mail.
                                             |  new Notification("New mail from John Doe",
                                             |                   { tag: 'message1' });

The result of this situation, if the user agent follows the algorithms here, is a single notification "New mail from John Doe".

6.3 Using the tag member for a single instance

The tag member can also be used by a single instance of an application to keep its notifications as current as possible as state changes.

For example, if Alice is using a chat application with Bob, and Bob sends multiple messages while Alice is idle, the application may prefer that Alice not see a desktop notification for each message.

// Bob says "Hi"
new Notification("Bob: Hi", { tag: 'chat_Bob' });

// Bob says "Are you free this afternoon?"
new Notification("Bob: Hi / Are you free this afternoon?", { tag: 'chat_Bob' });

The result of this situation is a single notification; the second one replaces the first having the same tag. In a platform that queues notifications (first-in-first-out), using the tag allows the notification to also maintain its position in the queue. Platforms where the newest notifications are shown first, a similar result could be achieved using the close() method.

References

[BIDI]
Unicode Bidirectional Algorithm, Mark Davis. Unicode Consortium.
[DOM]
DOM, Anne van Kesteren, Aryeh Gregor and Ms2ger. WHATWG.
[FETCH]
Fetch, Anne van Kesteren. WHATWG.
[HTML]
HTML, Ian Hickson. WHATWG.
[LANG]
Tags for Identifying Languages; Matching of Language Tags, Addison Phillips and Mark Davis. IETF.
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels, Scott Bradner. IETF.
[URL]
URL, Anne van Kesteren. WHATWG.
[WEBIDL]
Web IDL, Cameron McCormack. W3C.

Acknowledgments

Thanks to Aharon (Vladimir) Lanin, Alex Russell, Arkadiusz Michalski, David Håsäther, Doug Turner, Drew Wilson, Edward O'Connor, Frederick Hirsch, Ian Hickson, Jake Archibald, James Graham, Jon Lee, Jonas Sicking, Michael Henretty, Olli Pettay, Reuben Morais, and Simon Pieters for being awesome.