mozilla

Revision 641237 of Using Web Notifications

  • Revision slug: Web/API/Notification/Using_Web_Notifications
  • Revision title: Using Web Notifications
  • Revision id: 641237
  • Created:
  • Creator: DavidWalsh
  • Is current revision? No
  • Comment

Revision Content

{{SeeCompatTable}}

Summary

The Web Notifications API allows a web page to send notifications that are displayed outside the page at the system level. This allows web apps to send information to a user even if the application is idle. One of the main obvious use cases is a webmail application that would notify the user each time a new e-mail is received, even if the user is doing something else with another application.

To display notification you need to first request the appropriate permission and then instantiate a {{domxref("Notification")}} object:

Notification.requestPermission( function(status) {
  console.log(status); // notifications will only be displayed if "granted"
  var n = new Notification("title", {body: "notification body"}); // this also shows the notification
});

Requesting permission

Web content

Before an app is able to send a notification, the user must grant the application the right to do so. This is a common requirement when an API tries to interact with something outside a web page. This guarantees to avoid notification "spam" for the well-being of the user.

An application that needs to send a notification can check the current permission status thanks to the {{domxref("Notification.permission")}} read only property. It can have one of three possible values:

  • default: the user didn't give any permission yet (and therefore no notification will be displayed to the user).
  • granted: the user explicitly accepted to be notified by the application.
  • denied: the user explicitly refused to be notified by the application.

Note: Chrome and Safari do not implement the permission property yet.

If the permission is not granted, the application has to use the {{domxref("Notification.requestPermission()")}} method to let the user make a choice. This method accepts a callback function that receives the permission chosen by the user in order to react to it.

It's a common practice to ask for the permission at the initialization of the app:

window.addEventListener('load', function () {
  Notification.requestPermission(function (status) {
    // This allows to use Notification.permission with Chrome/Safari
    if (Notification.permission !== status) {
      Notification.permission = status;
    }
  });
});

Note: Chrome does not allows to call {{domxref("Notification.requestPermission()")}} on the load event (see issue 274284).

Installed application

When an application is installed, it's possible to avoid to prompt the user for permission by adding the permission directly within the application manifest:

"permissions": {
  "desktop-notification": {
    "description": "Allows to display notifications on the user's desktop."
  }
}

Creating a notification

Creating a notification is simply done using the {{domxref("Notification")}} constructor. This constructor expects a title to display within the notification and some options to enhance the notification such as an {{domxref("Notification.icon","icon")}} or a text {{domxref("Notification.body","body")}}.

A notification is displayed as soon as possible when instantiated. To track the current state of a notification, four events are triggered at the {{domxref("Notification")}} instance level:

  • {{event("show")}}: triggered when the notification is displayed to the user.
  • {{event("click")}}: triggered when the user clicks on the notification.
  • {{event("close")}}: triggered when the notification is closed.
  • {{event("error")}}: triggered when something wrong happens with the notification (mostly when something prevents the notification from being displayed)

Those events can be tracked using the event handlers {{domxref("Notification.onshow","onshow")}}, {{domxref("Notification.onclick","onclick")}}, {{domxref("Notification.onclose","onclose")}}, or {{domxref("Notification.onerror","onerror")}}. Because {{domxref("Notification")}} also inherits from {{domxref("EventTarget")}}, it's possible to use the {{domxref("EventTarget.addEventListener","addEventListener()")}} method.

Note: Firefox and Safari close the notifications automatically after a few moments, e.g. 4  seconds.

This can also be done at the web application level using the {{domxref("Notification.close()")}} method, for example with the following code:

var n = new Notification("Hi!");
n.onshow = function () { 
  setTimeout(n.close, 5000); 
}

When you receive a "close" event, there is no guarantee that it's the user who closed the notification. This is in line with the specification, which states: "When a notification is closed, either by the underlying notifications platform or by the user, the close steps for it must be run."

Simple example

Assume the following basic HTML:

<button>Notify me!</button>

It's possible to handle notifications this way:

window.addEventListener('load', function () {
  // At first, let's check if we have permission for notification
  // If not, let's ask for it
  if (window.Notification && Notification.permission !== "granted") {
    Notification.requestPermission(function (status) {
      if (Notification.permission !== status) {
        Notification.permission = status;
      }
    });
  }

  var button = document.getElementsByTagName('button')[0];

  button.addEventListener('click', function () {
    // If the user agreed to get notified
    if (window.Notification && Notification.permission === "granted") {
      var n = new Notification("Hi!");
    }

    // If the user hasn't told if he wants to be notified or not
    // Note: because of Chrome, we are not sure the permission property
    // is set, therefore it's unsafe to check for the "default" value.
    else if (window.Notification && Notification.permission !== "denied") {
      Notification.requestPermission(function (status) {
        if (Notification.permission !== status) {
          Notification.permission = status;
        }

        // If the user said okay
        if (status === "granted") {
          var n = new Notification("Hi!");
        }

        // Otherwise, we can fallback to a regular modal alert
        else {
          alert("Hi!");
        }
      });
    }

    // If the user refuses to get notified
    else {
      // We can fallback to a regular modal alert
      alert("Hi!");
    }
  });
});

And the live result:

{{ EmbedLiveSample('Simple_example', '100%', 30) }}

Dealing with repeated notifications

In some cases it can be painful for the user to send him a high number of notifications--for example, if an application for instant messaging can notify a user for each incoming message. To avoid bloating the user desktop with hundreds of unnecessary notifications, it's possible to take over the queue of pending notifications.

To do this, it's possible to add a tag to any new notification. If a notification already has the same tag and has not been displayed yet, the new notification will replace that previous notification. If the notification with the same tag has been already displayed, the previous notification is closed and the new one is displayed.

Tag example

Assume the following basic HTML:

<button>Notify me!</button>

It's possible to handle multiple notifications this way:

window.addEventListener('load', function () {
  // At first, let's check if we have permission for notification
  // If not, let's ask for it
  if (window.Notification && Notification.permission !== "granted") {
    Notification.requestPermission(function (status) {
      if (Notification.permission !== status) {
        Notification.permission = status;
      }
    });
  }

  var button = document.getElementsByTagName('button')[0];

  button.addEventListener('click', function () {
    // If the user agreed to get notified
    // Let's try to send ten notifications
    if (window.Notification && Notification.permission === "granted") {
      for (var i = 0; i < 10; i++) {
        // Thanks to the tag, we should only see the "Hi! 9" notification
        var n = new Notification("Hi! " + i, {tag: 'soManyNotification'});
      }
    }

    // If the user hasn't told if he wants to be notified or not
    // Note: because of Chrome, we are not sure the permission property
    // is set, therefore it's unsafe to check for the "default" value.
    else if (window.Notification && Notification.permission !== "denied") {
      Notification.requestPermission(function (status) {
        if (Notification.permission !== status) {
          Notification.permission = status;
        }

        // If the user said okay
        if (status === "granted") {
          for (var i = 0; i < 10; i++) {
            // Thanks to the tag, we should only see the "Hi! 9" notification
            var n = new Notification("Hi! " + i, {tag: 'soManyNotification'});
          }
        }

        // Otherwise, we can fallback to a regular modal alert
        else {
          alert("Hi!");
        }
      });
    }

    // If the user refuses to get notified
    else {
      // We can fallback to a regular modal alert
      alert("Hi!");
    }
  });
});

And the live result:

{{ EmbedLiveSample('Tag_example', '100%', 30) }}

Specifications

Specification Status Comment
{{SpecName('Web Notifications')}} {{Spec2('Web Notifications')}} Initial specification.

Browser compatibility

{{page("/en-US/Web/API/Notification","Browser compatibility")}}

See also

  • {{ domxref("Notification") }}

Revision Source

<p>{{SeeCompatTable}}</p>
<h2 id="Summary">Summary</h2>
<p>The Web Notifications API allows a web page to send notifications that are displayed outside the page at the system level. This allows web apps to send information to a user even if the application is idle. One of the main obvious use cases is a webmail application that would notify the user each time a new e-mail is received, even if the user is doing something else with another application.</p>
<p>To display notification you need to first request the appropriate permission and then instantiate a {{domxref("Notification")}} object:</p>
<pre class="brush: js">
Notification.requestPermission( function(status) {
  console.log(status); // notifications will only be displayed if "granted"
  var n = new Notification("title", {body: "notification body"}); // this also shows the notification
});
</pre>
<h2 id="Requesting_permission">Requesting permission</h2>
<h3 id="Web_content">Web content</h3>
<p>Before an app is able to send a notification, the user must grant the application the right to do so. This is a common requirement when an API tries to interact with something outside a web page. This guarantees to avoid notification "spam" for the well-being of the user.</p>
<p>An application that needs to send a notification can check the current permission status thanks to the {{domxref("Notification.permission")}} read only property. It can have one of three possible values:</p>
<ul>
 <li><code>default</code>: the user didn't give any permission yet (and therefore no notification will be displayed to the user).</li>
 <li><code>granted</code>: the user explicitly accepted to be notified by the application.</li>
 <li><code>denied</code>: the user explicitly refused to be notified by the application.</li>
</ul>
<div class="note">
 <p><strong>Note:</strong> Chrome and Safari do not implement the <code>permission</code> property yet.</p>
</div>
<p>If the permission is not granted, the application has to use the {{domxref("Notification.requestPermission()")}} method to let the user make a choice. This method accepts a callback function that receives the permission chosen by the user in order to react to it.</p>
<p>It's a common practice to ask for the permission at the initialization of the app:</p>
<pre class="brush: js">
window.addEventListener('load', function () {
  Notification.requestPermission(function (status) {
    // This allows to use Notification.permission with Chrome/Safari
    if (Notification.permission !== status) {
      Notification.permission = status;
    }
  });
});</pre>
<div class="note">
 <p><strong>Note:</strong> Chrome does not allows to call {{domxref("Notification.requestPermission()")}} on the <code>load</code> event (see <a href="https://code.google.com/p/chromium/issues/detail?id=274284" title="https://code.google.com/p/chromium/issues/detail?id=274284">issue 274284</a>).</p>
</div>
<h3 id="Installed_application">Installed application</h3>
<p>When an application is installed, it's possible to avoid to prompt the user for permission by adding the permission directly within the <a href="/en-US/docs/Web/Apps/Manifest" title="/en-US/docs/Web/Apps/Manifest">application manifest</a>:</p>
<pre class="brush: json">
"permissions": {
  "desktop-notification": {
    "description": "Allows to display notifications on the user's desktop."
  }
}</pre>
<h2 id="Creating_a_notification">Creating a notification</h2>
<p>Creating a notification is simply done using the {{domxref("Notification")}} constructor. This constructor expects a title to display within the notification and some options to enhance the notification such as an {{domxref("Notification.icon","icon")}} or a text {{domxref("Notification.body","body")}}.</p>
<p>A notification is displayed as soon as possible when instantiated. To track the current state of a notification, four events are triggered at the {{domxref("Notification")}} instance level:</p>
<ul>
 <li>{{event("show")}}: triggered when the notification is displayed to the user.</li>
 <li>{{event("click")}}: triggered when the user clicks on the notification.</li>
 <li>{{event("close")}}: triggered when the notification is closed.</li>
 <li>{{event("error")}}: triggered when something wrong happens with the notification (mostly when something prevents the notification from being displayed)</li>
</ul>
<p>Those events can be tracked using the event handlers {{domxref("Notification.onshow","onshow")}}, {{domxref("Notification.onclick","onclick")}}, {{domxref("Notification.onclose","onclose")}}, or {{domxref("Notification.onerror","onerror")}}. Because {{domxref("Notification")}} also inherits from {{domxref("EventTarget")}}, it's possible to use the {{domxref("EventTarget.addEventListener","addEventListener()")}} method.</p>
<div class="note">
 <p><strong>Note:</strong> Firefox and Safari close the notifications automatically after a few moments, e.g. 4&nbsp; seconds.</p>
 <p>This can also be done at the web application level using the {{domxref("Notification.close()")}} method, for example with the following code:</p>
 <pre class="brush: js">
var n = new Notification("Hi!");
n.onshow = function () { 
  setTimeout(n.close, 5000); 
}
</pre>
 <p>When you receive a "close" event, there is no guarantee that it's the user who closed the notification. This is in line with the specification, which states: "When a notification is closed, either by the underlying notifications platform or by the user, the close steps for it must be run."</p>
</div>
<h3 id="Simple_example">Simple example</h3>
<p>Assume the following basic HTML:</p>
<pre class="brush: html">
&lt;button&gt;Notify me!&lt;/button&gt;</pre>
<p>It's possible to handle notifications this way:</p>
<pre class="brush: js">
window.addEventListener('load', function () {
  // At first, let's check if we have permission for notification
  // If not, let's ask for it
  if (window.Notification &amp;&amp; Notification.permission !== "granted") {
    Notification.requestPermission(function (status) {
      if (Notification.permission !== status) {
        Notification.permission = status;
      }
    });
  }

  var button = document.getElementsByTagName('button')[0];

  button.addEventListener('click', function () {
    // If the user agreed to get notified
    if (window.Notification &amp;&amp; Notification.permission === "granted") {
      var n = new Notification("Hi!");
    }

    // If the user hasn't told if he wants to be notified or not
    // Note: because of Chrome, we are not sure the permission property
    // is set, therefore it's unsafe to check for the "default" value.
    else if (window.Notification &amp;&amp; Notification.permission !== "denied") {
      Notification.requestPermission(function (status) {
        if (Notification.permission !== status) {
          Notification.permission = status;
        }

        // If the user said okay
        if (status === "granted") {
          var n = new Notification("Hi!");
        }

        // Otherwise, we can fallback to a regular modal alert
        else {
          alert("Hi!");
        }
      });
    }

    // If the user refuses to get notified
    else {
      // We can fallback to a regular modal alert
      alert("Hi!");
    }
  });
});</pre>
<p>And the live result:</p>
<p>{{ EmbedLiveSample('Simple_example', '100%', 30) }}</p>
<h2 id="Dealing_with_repeated_notifications">Dealing with repeated notifications</h2>
<p>In some cases it can be painful for the user to send him a high number of notifications--for example, if an application for instant messaging can notify a user for each incoming message. To avoid bloating the user desktop with hundreds of unnecessary notifications, it's possible to take over the queue of pending notifications.</p>
<p>To do this, it's possible to add a tag to any new notification. If a notification already has the same tag and has not been displayed yet, the new notification will replace that previous notification. If the notification with the same tag has been already displayed, the previous notification is closed and the new one is displayed.</p>
<h3 id="Tag_example">Tag example</h3>
<p>Assume the following basic HTML:</p>
<pre class="brush: html">
&lt;button&gt;Notify me!&lt;/button&gt;</pre>
<p>It's possible to handle multiple notifications this way:</p>
<pre class="brush: js">
window.addEventListener('load', function () {
  // At first, let's check if we have permission for notification
  // If not, let's ask for it
  if (window.Notification &amp;&amp; Notification.permission !== "granted") {
    Notification.requestPermission(function (status) {
      if (Notification.permission !== status) {
        Notification.permission = status;
      }
    });
  }

  var button = document.getElementsByTagName('button')[0];

  button.addEventListener('click', function () {
    // If the user agreed to get notified
    // Let's try to send ten notifications
    if (window.Notification &amp;&amp; Notification.permission === "granted") {
      for (var i = 0; i &lt; 10; i++) {
        // Thanks to the tag, we should only see the "Hi! 9" notification
        var n = new Notification("Hi! " + i, {tag: 'soManyNotification'});
      }
    }

    // If the user hasn't told if he wants to be notified or not
    // Note: because of Chrome, we are not sure the permission property
    // is set, therefore it's unsafe to check for the "default" value.
    else if (window.Notification &amp;&amp; Notification.permission !== "denied") {
      Notification.requestPermission(function (status) {
        if (Notification.permission !== status) {
          Notification.permission = status;
        }

        // If the user said okay
        if (status === "granted") {
          for (var i = 0; i &lt; 10; i++) {
            // Thanks to the tag, we should only see the "Hi! 9" notification
            var n = new Notification("Hi! " + i, {tag: 'soManyNotification'});
          }
        }

        // Otherwise, we can fallback to a regular modal alert
        else {
          alert("Hi!");
        }
      });
    }

    // If the user refuses to get notified
    else {
      // We can fallback to a regular modal alert
      alert("Hi!");
    }
  });
});</pre>
<p>And the live result:</p>
<p>{{ EmbedLiveSample('Tag_example', '100%', 30) }}</p>
<h2 id="Specifications">Specifications</h2>
<table class="standard-table">
 <thead>
  <tr>
   <th scope="col">Specification</th>
   <th scope="col">Status</th>
   <th scope="col">Comment</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td>{{SpecName('Web Notifications')}}</td>
   <td>{{Spec2('Web Notifications')}}</td>
   <td>Initial specification.</td>
  </tr>
 </tbody>
</table>
<h2 id="Browser_compatibility">Browser compatibility</h2>
<p>{{page("/en-US/Web/API/Notification","Browser compatibility")}}</p>
<h2 id="See_also">See also</h2>
<ul>
 <li>{{ domxref("Notification") }}</li>
</ul>
Revert to this revision