Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions files/en-us/web/api/notification/click_event/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ browser-compat: api.Notification.click_event

{{APIRef("Web Notifications")}}{{securecontext_header}} {{AvailableInWorkers}}

The **`click`** event of the {{domxref("Notification")}}
interface fires when the user clicks on displayed {{domxref("Notification")}}.
The **`click`** event of the {{domxref("Notification")}} interface fires when the user clicks on a [non-persistent notification](/en-US/docs/Web/API/Notifications_API#non-persistent_notifications).

The default behavior is to move the focus to the viewport of the notification's related
[browsing context](https://html.spec.whatwg.org/multipage/browsers.html#browsing-context).
Expand Down
2 changes: 1 addition & 1 deletion files/en-us/web/api/notification/close_event/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ browser-compat: api.Notification.close_event

{{APIRef("Web Notifications")}}{{securecontext_header}} {{AvailableInWorkers}}

The **`close`** event of the {{domxref("Notification")}} interface fires when a {{domxref("Notification")}} is closed.
The **`close`** event of the {{domxref("Notification")}} interface fires when a [non-persistent notification](/en-US/docs/Web/API/Notifications_API#non-persistent_notifications) is closed.

## Syntax

Expand Down
2 changes: 1 addition & 1 deletion files/en-us/web/api/notification/error_event/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ browser-compat: api.Notification.error_event

{{APIRef("Web Notifications")}}{{securecontext_header}} {{AvailableInWorkers}}

The **`error`** event of the {{domxref("Notification")}} interface fires when something goes wrong with a {{domxref("Notification")}} (in many cases an error preventing the notification from being displayed.)
The **`error`** event of the {{domxref("Notification")}} interface fires when something goes wrong with a [non-persistent notification](/en-US/docs/Web/API/Notifications_API#non-persistent_notifications) (in many cases an error preventing the notification from being displayed.)

## Syntax

Expand Down
10 changes: 5 additions & 5 deletions files/en-us/web/api/notification/notification/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ browser-compat: api.Notification.Notification

{{APIRef("Web Notifications")}}{{securecontext_header}} {{AvailableInWorkers}}

The **`Notification()`** constructor creates a new {{domxref("Notification")}} object instance, which represents a user notification.

Trying to create a notification inside the {{domxref("ServiceWorkerGlobalScope")}} using the `Notification()` constructor will throw a `TypeError`. Use {{domxref("ServiceWorkerRegistration.showNotification()")}} instead.
The **`Notification()`** constructor creates a new {{domxref("Notification")}} object instance, which represents a [non-persistent notification](/en-US/docs/Web/API/Notifications_API#non-persistent_notifications).

You must first get permission before being able to display notifications, using {{domxref("Notification.requestPermission()")}}. The permission may not be grantable, for example if the page is in private browsing mode.

This constructor throws a {{jsxref("TypeError")}} when called in nearly all mobile browsers and this is unlikely to change, because web pages on mobile devices almost never "run in the background", which is the main use case for notifications. Instead, you need to register a service worker and use {{domxref("ServiceWorkerRegistration.showNotification()")}}. See [Chrome issue](https://crbug.com/481856) for more information.
Trying to create a notification inside the {{domxref("ServiceWorkerGlobalScope")}} using the `Notification()` constructor will throw a `TypeError`. Use {{domxref("ServiceWorkerRegistration.showNotification()")}} instead.

This constructor throws a {{jsxref("TypeError")}} when called in nearly all mobile browsers and this is unlikely to change, because web pages on mobile devices almost never "run in the background", which is the main use case for notifications. Instead, you need to register a service worker and create a [persistent notification](/en-US/docs/Web/API/Notifications_API#persistent_notifications) by calling {{domxref("ServiceWorkerRegistration.showNotification()")}}. See [Chrome issue](https://crbug.com/481856) for more information.

## Syntax

Expand All @@ -30,7 +30,7 @@ new Notification(title, options)
- `options` {{optional_inline}}
- : An options object containing any custom settings that you want to apply to the notification. The possible options are:
- `actions` {{optional_inline}}
- : Must be unspecified or an empty array. `actions` is only supported for persistent notifications fired from a service worker using {{domxref("ServiceWorkerRegistration.showNotification()")}}.
- : Must be unspecified or an empty array. The `actions` option is only supported for [persistent notifications](/en-US/docs/Web/API/Notifications_API#persistent_notifications).
- `badge` {{optional_inline}}
- : A string containing the URL of the image used to represent the notification when there isn't enough space to display the notification itself; for example, the Android Notification Bar. On Android devices, the badge should accommodate devices up to 4x resolution, about 96x96px, and the image will be automatically masked.
- `body` {{optional_inline}}
Expand Down
2 changes: 1 addition & 1 deletion files/en-us/web/api/notification/show_event/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ browser-compat: api.Notification.show_event

{{APIRef("Web Notifications")}}{{securecontext_header}} {{AvailableInWorkers}}

The **`show`** event of the {{domxref("Notification")}} interface fires when a {{domxref("Notification")}} is displayed.
The **`show`** event of the {{domxref("Notification")}} interface fires when a [non-persistent notification](/en-US/docs/Web/API/Notifications_API#non-persistent_notifications) is displayed.

## Syntax

Expand Down
107 changes: 92 additions & 15 deletions files/en-us/web/api/notifications_api/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,105 @@ The Notifications API allows web pages to control the display of system notifica

## Concepts and usage

On supported platforms, showing a system notification generally involves two things. First, the user needs to grant the current origin permission to display system notifications, which is generally done when the app or site initializes, using the {{domxref("Notification.requestPermission_static", "Notification.requestPermission()")}} method.
This method should only be called when handling a user gesture, such as when handling a mouse click. For example:
### Requesting permission

A website can only display notifications if the user has granted it permission to do so. To ask permission, the website needs to call the static {{domxref("Notification.requestPermission_static", "Notification.requestPermission()")}} method. This method should only be called when handling a user gesture, such as when handling a mouse click. For example:

```js
btn.addEventListener("click", () => {
let promise = Notification.requestPermission();
// wait for permission
button.addEventListener("click", async () => {
const permission = await Notification.requestPermission();
if (permission === "granted") {
// we can show the notification
} else {
// we can't show the notification
}
});
```

This will spawn a request dialog, along the following lines:
The `requestPermission()` method returns a {{jsxref("Promise")}} which resolves to one of the following three string values:

- `"granted"`: the user granted permission.
- `"denied"`: the user denied permission.
- `"default"`: the user has neither granted nor denied permission.

When the site calls `requestPermission()`, if the user has not already granted or denied permission for this {{glossary("origin")}}, then the browser shows the user a dialog asking them if they want to grant or deny permission:

![A dialog box asking the user to allow notifications from that origin. There are options to never allow or allow notifications.](screen_shot_2019-12-11_at_9.59.14_am.png)

From here the user can choose to allow notifications from this origin, or block them. Once a choice has been made, the setting will generally persist for the current session.
Once the user has made a choice, the browser will resolve the returned promise with their choice, and remember it.

If the user has already chosen to grant or deny notifications for this origin, then `requestPermission()` will immediately resolve the promise with their choice.

### Persistent and non-persistent notifications

The specification distinguishes two sorts of notifications, _persistent notifications_ and _non-persistent notifications_. These serve different use cases and involve different APIs.

#### Persistent notifications

Persistent notifications are created in a web page or a service worker, by calling {{domxref("ServiceWorkerRegistration.showNotification()")}}, and any user interaction with the notification is always handled in the service worker.

The browser should display the notification in the platform's notification center, if that is available, and the notification may persist in the notification center until it is removed (for example, because the user closed it).

When a persistent notification is created, you can pass it an array of [`action`](/en-US/docs/Web/API/ServiceWorkerRegistration/showNotification#actions) objects: these are typically things the user might want the website to do in response to the notification. For example, an email app might display a notification which gives the user the chance to delete the email or open it.

```js
const registration = await navigator.serviceWorker.ready;
registration.showNotification("You have a new email", {
actions: [
{ action: "open", title: "Open this email" },
{ action: "delete", title: "Delete this email" },
],
});
```

The actions will be presented to the user in the notification, for example as buttons they can press or options they can select.

When the user clicks a persistent notification, the {{domxref("ServiceWorkerGlobalScope.notificationclick_event", "notificationclick")}} event is fired in the service worker's global scope. If the user selected an action, it is given as the {{domxref("NotificationEvent.action", "action")}} property of the event passed into the `notificationclick` handler, and the service worker can use it to decide what to do:

```js
self.addEventListener("notificationclick", (event) => {
switch (event.action) {
case "open":
clients.openWindow("actions/open.html");
break;
case "delete":
clients.openWindow("actions/delete.html");
break;
}
});
```

#### Non-persistent notifications

Non-persistent notifications are always created in a web page, by calling the {{domxref("Notification.Notification()", "Notification()")}} constructor, and user interaction with the notification is always handled in the web page.

The browser should not display the notification in the platform's notification center, and should automatically close the notification after a few seconds.

The web page can handle user interactions with the notification by listening for the {{domxref("Notification.click_event", "click")}} and {{domxref("Notification.close_event", "close")}} events.

```js
const notification = new Notification("Hello!");

notification.addEventListener("click", () => {
console.log("clicked!");
});

notification.addEventListener("close", () => {
console.log("closed!");
});
```

These events are passed a generic {{domxref("Event")}} object — unlike a persistent notification, with a non-persistent notification you can't provide actions, and therefore can't be informed about which action the user chose.

#### Which type should you use?

The most common use case for a notification is when something happens in your web app that the user should know about, but they should not be forced to immediately stop whatever else they are doing. For example, your web app is an email app and you have received a new email. You might want the user to know that they have an email, and when they are ready to deal with it, you want to handle their response — for example, to read the email or delete it unread.

Next, a new notification is created using the {{domxref("Notification.Notification","Notification()")}} constructor. This must be passed a title argument, and can optionally be passed an options object to specify options, such as text direction, body text, icon to display, notification sound to play, and more.
To meet this use case you need to use persistent notifications, because web pages are inherently ephemeral. The user could close the page at any time, and if they do so, the notification object is destroyed along with any event listeners, so your web app will not able to handle the user's response.

In addition, the Notifications API spec specifies a number of additions to the [ServiceWorker API](/en-US/docs/Web/API/Service_Worker_API), to allow service workers to fire notifications.
However, if your notification is managed by a service worker, then when the user interacts with the notification, the browser will automatically resume your service worker and fire its `notificationclick` event.

> [!NOTE]
> To find out more about using notifications in your own app, read [Using the Notifications API](/en-US/docs/Web/API/Notifications_API/Using_the_Notifications_API).
On mobile devices, the situation for non-persistent notifications is even more challenging, because a mobile browser might stop a page from running as soon as it is put in the background. For this reason, Chromium-based browsers don't support non-persistent notifications at all on mobile, and the `Notification()` constructor will throw an exception.

## Interfaces

Expand All @@ -48,13 +125,13 @@ In addition, the Notifications API spec specifies a number of additions to the [
### Extensions to other interfaces

- {{domxref("ServiceWorkerGlobalScope/notificationclick_event", "notificationclick")}} event
- : Occurs when a user clicks on a displayed notification.
- : Occurs when a user clicks on a persistent notification.
- {{domxref("ServiceWorkerGlobalScope/notificationclose_event", "notificationclose")}} event
- : Occurs when a user closes a displayed notification.
- : Occurs when a user closes a persistent notification.
- {{domxref("ServiceWorkerRegistration.getNotifications()")}}
- : Returns a list of the notifications in the order that they were created from the current origin via the current service worker registration.
- : Returns a list of persistent notifications in the order that they were created from the current origin via the current service worker registration.
- {{domxref("ServiceWorkerRegistration.showNotification()")}}
- : Displays the notification with the requested title.
- : Displays the persistent notification with the requested title.

## Specifications

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,9 @@ browser-compat: api.ServiceWorkerGlobalScope.notificationclick_event

{{APIRef("Web Notifications")}}{{SecureContext_Header}}{{AvailableInWorkers("service")}}

The **`notificationclick`** event of the {{domxref("ServiceWorkerGlobalScope")}} interface is fired to indicate that a system notification spawned by {{domxref("ServiceWorkerRegistration.showNotification()")}} has been clicked.
The **`notificationclick`** event of the {{domxref("ServiceWorkerGlobalScope")}} interface is fired to indicate that the user has clicked a [persistent notification](/en-US/docs/Web/API/Notifications_API#persistent_notifications) associated with this service worker.

Notifications created on the main thread or in workers which aren't service workers
using the {{domxref("Notification.Notification","Notification()")}} constructor will
instead receive a {{domxref("Notification/click_event", "click")}} event on the {{domxref("Notification")}} object
itself.
[Non-persistent notifications](/en-US/docs/Web/API/Notifications_API#non-persistent_notifications), created using the {{domxref("Notification.Notification","Notification()")}} constructor on the main thread or in workers which aren't service workers, will instead receive a {{domxref("Notification/click_event", "click")}} event on the {{domxref("Notification")}} object itself.

This event is not cancelable and does not bubble.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,9 @@ browser-compat: api.ServiceWorkerGlobalScope.notificationclose_event

{{APIRef("Web Notifications")}}{{SecureContext_Header}}{{AvailableInWorkers("service")}}

The **`notificationclose`** event of the {{domxref("ServiceWorkerGlobalScope")}} interface fires when a user closes a displayed notification spawned by {{domxref("ServiceWorkerRegistration.showNotification()")}}.
The **`notificationclose`** event of the {{domxref("ServiceWorkerGlobalScope")}} interface fires when the user closes a [persistent notification](/en-US/docs/Web/API/Notifications_API#persistent_notifications) associated with this service worker.

Notifications created on the main thread or in workers which aren't service workers
using the {{domxref("Notification.Notification","Notification()")}} constructor will
instead receive a {{domxref("Notification/close_event", "close")}} event on the {{domxref("Notification")}} object
itself.
[Non-persistent notifications](/en-US/docs/Web/API/Notifications_API#non-persistent_notifications), created using the {{domxref("Notification.Notification","Notification()")}} constructor on the main thread or in workers which aren't service workers, will instead receive a {{domxref("Notification/close_event", "close")}} event on the {{domxref("Notification")}} object itself.

This event is not cancelable and does not bubble.

Expand Down
Loading