• Skip to main content
  • Select language
  • Skip to search
MDN Web Docs
  • Technologies
    • HTML
    • CSS
    • JavaScript
    • Graphics
    • HTTP
    • APIs / DOM
    • WebExtensions
    • MathML
  • References & Guides
    • Learn web development
    • Tutorials
    • References
    • Developer Guides
    • Accessibility
    • Game development
    • ...more docs
Add-ons
  1. MDN
  2. Mozilla
  3. Add-ons
  4. Overlay extensions
  5. XUL School Tutorial
  6. User Notifications and Alerts

User Notifications and Alerts

In This Article
  1. The notificationbox element
  2. The Alerts Service
  3. Custom alerts

Add-ons using the techniques described in this document are considered a legacy technology in Firefox. Don't use these techniques to develop new add-ons. Use WebExtensions instead. If you maintain an add-on which uses the techniques described here, consider migrating it to use WebExtensions.

From Firefox 53 onwards, no new legacy add-ons will be accepted on addons.mozilla.org (AMO).

From Firefox 57 onwards, WebExtensions will be the only supported extension type, and Firefox will not load other types.

Even before Firefox 57, changes coming up in the Firefox platform will break many legacy extensions. These changes include multiprocess Firefox (e10s), sandboxing, and multiple content processes. Legacy extensions that are affected by these changes should migrate to WebExtensions if they can. See the "Compatibility Milestones" document for more.

A wiki page containing resources, migration paths, office hours, and more, is available to help developers transition to the new technologies.

« PreviousNext »

It is often the case that extensions need to notify users about important events, often requiring some response. Using modal dialogs and alerts is usually a bad idea. They interrupt the user's workflow, demanding immediate action before anything else can be done. Users will find them annoying and probably will learn to dismiss them as quickly as possible without even reading what they have to say. Or they will just get rid of your add-on.

This section lists a few alternatives that give you the possibility of notifying the user and requesting action without being too annoying.

The notificationbox element

You have probably seen these before. The "remember password" prompt is the one that shows up the most often. They are thin boxes that appear from beneath the tab list and above the page content, with some text and maybe a few buttons. This kind of notification is implemented with a notificationbox.

This kind on notification is very easy to implement, it doesn't interrupt the user and is easy to read and dismiss, so it is our recommended way of displaying alerts and notifications. There's a catch, though: these notifications are inside the current tab, so switching tabs will make a notification disappear. The notification shows up again when you come back to the tab that displayed it. This means that these notifications make the most sense when they are related to the page currently being displayed, such as a page trying to install an add-on, or a site you just entered a password on.

Notification boxes are very easy to create, and are very customizable:

let nb = gBrowser.getNotificationBox();
let acceptButton = new Object();
let declineButton = new Object();
let message = 
  this._bundle.getString("xulschoolhello.friendMessage.label");
let that = this;
acceptButton.label =
  this._bundle.getString("xulschoolhello.acceptButton.label");
acceptButton.accessKey =
  this._bundle.getString("xulschoolhello.acceptButton.accesskey");
acceptButton.popup = null;
acceptButton.callback = function() { that.acceptRequest(); };
// similarly for decline button.
nb.appendNotification(
  message, "xulschoolhello-friend-notification",
  "chrome://xulschoolhello/skin/friend-notification.png",
  nb.PRIORITY_INFO_HIGH, [ acceptButton, declineButton ]);

All browser tabs have a notification box by default, so you don't need to do any overlaying. The notificationbox elements can be obtained from the gBrowser object. In this case we don't pass any arguments to getNotificationBox so that we get the notification box that corresponds to the tab currently on display. The appendNotification method takes the message, id, image (32x32), level and buttons. The level argument determines the "strength" of the message, indicated by its background color when it is displayed. You should look for the level that better fits your message, and use the lowest applicable level, to prevent the user from getting used to dismissing high-level notifications. The buttons are represented by simple JS data objects. This is all explained in detail in the notificationbox page.

Notification boxes are designed to be easily dismissed. All notifications have an additional close button, so you should take into account that it's possible that none of your custom buttons will be clicked. Also, clicking on any of your custom buttons will cause the notification to be immediately closed, so you should only use notification boxes for single-step processes.

The Alerts Service

This is a very good option when you want to alert users about events without requiring input from them. Alerts are displayed in an OS-specific way, so their look is native. You can associate an action to the user clicking on the alert. Another advantage is that you use an XPCOM service to do this (nsIAlertsService), so you can easily trigger alerts from chrome and non-chrome code. On the other hand, alerts are displayed only temporarily

Using the Alerts Service is similar to using notification boxes:

let alertsService =
  Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService);
let title = this._bundle.getString("xulschoolhello.greeting.title");
let message = this._bundle.getString("xulschoolhello.greeting.label");
alertsService.showAlertNotification(
  "chrome://xulschoolhello/skin/hello-notification.png",
  title, message, true, "", this, "XULSchool Hello Message");

We pass this as an argument, assuming that this is an object that implements nsIObserver. We do this when we need to handle clicks on the alert box. The image can have any size, but it is recommended that you use a medium, fixed size.

The main disadvantage of using alerts is that support for the Alerts Service is not guaranteed for all platforms and Firefox versions. Support for Windows has existed since Firefox 2. For Mac OS X, support was added on Firefox 3, and only through a third-party tool called Growl. On Linux systems, we have confirmed that it works on Firefox 3 on Ubuntu Linux, but we haven't tested all distributions and Firefox versions.

Because of the inconsistent support and temporary nature of these alerts, we don't recommend using this service to show information the user needs to know and can't get in any other way.

Custom alerts

Creating custom solutions for alerting the user is not complicated, given the advantages of XUL overlays and CSS positioning. However, these solutions are prone to be buggy and have accessibility issues. You should use the 2 alternatives mentioned above whenever possible. If none of those fit your needs then this is an acceptable solution.

An easy way to display alerts is to include a hidden box in your overlay, which you can fill with any content you need before removing the hidden attribute so that it is displayed to the user. The best locations for this kind of box are above and below the tab browser. Below is preferrable because it only cuts the bottom part of the current page, as opposed to pushing down all tabs and content. Notification boxes are a good guideline to what you should aim for: thin, informative and easy to dismiss.

Another option is to also add a hidden box to the overlay, but use CSS positioning to locate it where you want. This usually means that the box will be hovering on top of the page's content, and there are a few things you must know about this. First of all, switching tabs will probably make your alert disappear. This is probably due to the fact that the browser tab box uses a deck internally, and that affects z-indexing. You'll have to code around this using tab events in order to know when to re-display your alert. Another problem you need to take into account is that transparency of floating XUL on the Mac OS version of Firefox 2 doesn't work. You'll end up with a box with a white background you can't get rid of . On Firefox 3 and above, this seems to have been corrected, using the panel element.

The bottom right corner of the browser is the recommended location for an alert, because it normally doesn't block the part of the content where the user is reading, or the most important parts of page content, such as menus and titles.

Remember this is not a recommended practice. Imagine having multiple extensions notifying you in their own custom way, probably even at the same time! This is not good from a UI perspective, so you consider custom alerts the very last resort.

« PreviousNext »

This tutorial was kindly donated to Mozilla by Appcoast.

Document Tags and Contributors

 Contributors to this page: wbamberg, snoedel, teoli, Jorge.villalobos
 Last updated by: wbamberg, Jul 4, 2016, 1:46:56 PM
See also
  1. WebExtensions
  2. Getting started
    1. What are WebExtensions?
    2. Your first WebExtension
    3. Your second WebExtension
    4. Anatomy of a WebExtension
    5. Example WebExtensions
  3. How to
    1. Intercept HTTP requests
    2. Modify a web page
    3. Add a button to the toolbar
    4. Implement a settings page
  4. Concepts
    1. Using the JavaScript APIs
    2. User interface components
    3. Content scripts
    4. Match patterns
    5. Internationalization
    6. Content Security Policy
    7. Native messaging
  5. Porting
    1. Porting a Google Chrome extension
    2. Porting a legacy Firefox add-on
    3. Embedded WebExtensions
    4. Comparison with the Add-on SDK
    5. Comparison with XUL/XPCOM extensions
    6. Chrome incompatibilities
  6. Firefox workflow
    1. Temporary Installation in Firefox
    2. Debugging
    3. Getting started with web-ext
    4. web-ext command reference
    5. WebExtensions and the Add-on ID
    6. Publishing your WebExtension
  7. JavaScript APIs
    1. Browser support for JavaScript APIs
    2. alarms
    3. bookmarks
    4. browserAction
    5. browsingData
    6. commands
    7. contextMenus
    8. contextualIdentities
    9. cookies
    10. downloads
    11. events
    12. extension
    13. extensionTypes
    14. history
    15. i18n
    16. identity
    17. idle
    18. management
    19. notifications
    20. omnibox
    21. pageAction
    22. runtime
    23. sessions
    24. sidebarAction
    25. storage
    26. tabs
    27. topSites
    28. webNavigation
    29. webRequest
    30. windows
  8. Manifest keys
    1. applications
    2. author
    3. background
    4. browser_action
    5. chrome_url_overrides
    6. commands
    7. content_scripts
    8. content_security_policy
    9. default_locale
    10. description
    11. developer
    12. homepage_url
    13. icons
    14. manifest_version
    15. name
    16. omnibox
    17. options_ui
    18. page_action
    19. permissions
    20. short_name
    21. sidebar_action
    22. version
    23. web_accessible_resources
  9. Add-on SDK
  10. Getting started
    1. Installation
    2. Getting started
    3. Troubleshooting
  11. High-Level APIs
    1. addon-page
    2. base64
    3. clipboard
    4. context-menu
    5. hotkeys
    6. indexed-db
    7. l10n
    8. notifications
    9. page-mod
    10. page-worker
    11. panel
    12. passwords
    13. private-browsing
    14. querystring
    15. request
    16. selection
    17. self
    18. simple-prefs
    19. simple-storage
    20. system
    21. tabs
    22. timers
    23. ui
    24. url
    25. webextension
    26. widget
    27. windows
  12. Low-Level APIs
    1. /loader
    2. chrome
    3. console/plain-text
    4. console/traceback
    5. content/content
    6. content/loader
    7. content/mod
    8. content/symbiont
    9. content/worker
    10. core/heritage
    11. core/namespace
    12. core/promise
    13. dev/panel
    14. event/core
    15. event/target
    16. frame/hidden-frame
    17. frame/utils
    18. fs/path
    19. io/byte-streams
    20. io/file
    21. io/text-streams
    22. lang/functional
    23. lang/type
    24. loader/cuddlefish
    25. loader/sandbox
    26. net/url
    27. net/xhr
    28. places/bookmarks
    29. places/favicon
    30. places/history
    31. platform/xpcom
    32. preferences/event-target
    33. preferences/service
    34. remote/child
    35. remote/parent
    36. stylesheet/style
    37. stylesheet/utils
    38. system/child_process
    39. system/environment
    40. system/events
    41. system/runtime
    42. system/unload
    43. system/xul-app
    44. tabs/utils
    45. test/assert
    46. test/harness
    47. test/httpd
    48. test/runner
    49. test/utils
    50. ui/button/action
    51. ui/button/toggle
    52. ui/frame
    53. ui/id
    54. ui/sidebar
    55. ui/toolbar
    56. util/array
    57. util/collection
    58. util/deprecate
    59. util/list
    60. util/match-pattern
    61. util/object
    62. util/uuid
    63. window/utils
  13. Firefox for Android
  14. Getting started
    1. Walkthrough
    2. Debugging
    3. Code snippets
  15. APIs
    1. Accounts.jsm
    2. BrowserApp
    3. HelperApps.jsm
    4. Home.jsm
    5. HomeProvider.jsm
    6. JavaAddonManager.jsm
    7. NativeWindow
    8. Notifications.jsm
    9. PageActions.jsm
    10. Prompt.jsm
    11. RuntimePermissions.jsm
    12. Snackbars.jsm
    13. Sound.jsm
    14. Tab
  16. Legacy
  17. Restartless extensions
    1. Overview
  18. Overlay extensions
    1. Overview
  19. Themes
  20. Lightweight themes
    1. Overview
  21. Complete themes
    1. Overview
  22. Publishing add-ons
  23. Guides
    1. Signing and distribution overview
    2. Submit an add-on
    3. Review policies
    4. Developer agreement
    5. Featured add-ons
    6. Contact addons.mozilla.org
  24. Community and support
  25. Channels
    1. Add-ons blog
    2. Add-on forums
    3. Stack Overflow
    4. Development newsgroup
    5. IRC Channel