Class Notification

All Implemented Interfaces:
PartialStateHolder, StateHolder, TransientStateHolder, ComponentSystemEventListener, FacesListener, SystemEventListenerHolder, EventListener

public class Notification extends ScriptFamily

The <o:notification> is a UIComponent which integrates the browser Web Notifications API with SSE (Server-Sent Events) based push. It opens a one-way (server to client) SSE connection and shows incoming push messages as browser notifications.

Prerequisites

This component requires the PWAResourceHandler to be activated by adding the following line to the <h:head> because it provides the service worker mandatory for cross-platform notification support via ServiceWorkerRegistration.showNotification():

 <link rel="manifest" href="#{resource['omnifaces:manifest.webmanifest']}" />
 

The browser notification permission must be requested via a user gesture before any notification can be shown:

 <button type="button" onclick="OmniFaces.Notification.requestPermission()">Enable Notifications</button>
 

The CDI backing bean must have at least one @Push(type=NOTIFICATION) qualified injection point using the channel name matching the channel attribute of this component, so that the SseEndpoint will be auto-activated.

Basic Usage

Declare the <o:notification> tag in the Faces view with a channel name.

 <o:notification channel="notifications" />
 

In the server side, inject the push context and send notification messages created via createNotificationMessage(String, String).

 @Inject @Push(type=NOTIFICATION)
 private PushContext notifications;

 public void sendNotification() {
     notifications.send(Notification.createNotificationMessage("Order shipped", "Your order #1234 has been shipped."));
 }
 

You can also add a URL so that clicking the notification will navigate to it:

 notifications.send(Notification.createNotificationMessage("Order shipped", "Your order has been shipped.", "https://example.com/orders/1234"));
 

Relative URLs are also accepted:

 notifications.send(Notification.createNotificationMessage("Order shipped", "Your order has been shipped.", "/orders/1234"));
 

User-targeted Notifications

The optional user attribute can be set to the unique identifier of the logged-in user, so that notifications can be targeted to a specific user.

 <o:notification channel="notifications" user="#{request.remoteUser}" />
 

The notification can then be sent to a specific user:

 notifications.send(Notification.createNotificationMessage("New message", "You have a new message."), recipientUserId);
 

Display behavior

By default, each new notification replaces the previous one from the same component. To let notifications stack independently instead, set the stacked attribute to true:

 <o:notification channel="notifications" stacked="true" />
 

The requireInteraction attribute controls whether the notification remains visible until the user explicitly interacts with it (click or dismiss), rather than auto-closing after a timeout. This is useful for important alerts that should not be missed:

 <o:notification channel="alerts" requireInteraction="true" />
 

The silent attribute suppresses the device's notification sound and vibration:

 <o:notification channel="updates" silent="true" />
 

Event Handlers

The <o:notification> supports click and close event handlers.

 <o:notification channel="notifications" onclick="handleClick" onclose="handleClose" />
 

The event's detail object contains data and tag. The data object contains the channel name and the optional url. The tag is set to the component's client ID (when not stacked) and is used by the browser for notification deduplication: a new notification with the same tag replaces the previous one instead of stacking.

 function handleClick(event) {
     console.log("Channel: " + event.detail.data.channel);
     console.log("URL (if any): " + event.detail.data.url);
     console.log("Tag (if not stacked): " + event.detail.tag);
 }
 function handleClose(event) {
     console.log("Channel: " + event.detail.data.channel);
     console.log("Tag (if not stacked): " + event.detail.tag);
 }
 

When you need to invoke a server-side action on notification click, use <h:commandScript> to bridge the client-side event to the server. For example, to mark a notification as read when the user clicks it:

 <o:notification channel="notifications" onclick="handleNotificationClick" />
 <h:form>
     <h:commandScript name="markAsRead" action="#{notificationBean.markAsRead}" />
 </h:form>
 

With this handler:

 function handleNotificationClick(event) {
     markAsRead({ "notification.url": event.detail.data?.url });
 }
 

And this bean:

 public void markAsRead() {
     var url = Faces.getRequestParameter("notification.url");
     // ...
 }
 

JavaScript API

The current permission can be checked via OmniFaces.Notification.getPermission(), which returns "granted", "denied", "default", or "unsupported".

 const notificationPermission = OmniFaces.Notification.getPermission();
 

You can use OmniFaces.Notification.show to programmatically show notifications using JavaScript. The first argument is the channel name, the second the title, the optional third the body, and the optional fourth a URL:

 OmniFaces.Notification.show("notifications", "Please wait ...");
 OmniFaces.Notification.show("notifications", "Hello!", "This is a notification.");
 OmniFaces.Notification.show("notifications", "Click me!", "Opens a link.", "https://omnifaces.org");
 

Platform limitations

The icon attribute is passed to the Notifications API, but custom notification icons are not guaranteed to work across all platforms. As of March 2026, macOS and Linux with GNOME always display the browser's own application icon instead, due to OS/desktop-environment-level policies. Custom icons do work on Windows and Android. Use PNG format at 192x192 or larger for best results.

 <o:notification channel="alerts" icon="#{resource['icons/alert.png']}" />
 
Since:
5.2
Author:
Bauke Scholtz
See Also:
  • Field Details

    • COMPONENT_TYPE

      public static final String COMPONENT_TYPE
      The component type, which is "org.omnifaces.cdi.push.Notification".
      See Also:
  • Constructor Details

    • Notification

      public Notification()
  • Method Details

    • createNotificationMessage

      public static Notification.Message createNotificationMessage(String title)
      Creates a notification message with only a title for use with PushContext.send().
      Parameters:
      title - The notification title.
      Returns:
      A new Notification.Message instance.
    • createNotificationMessage

      public static Notification.Message createNotificationMessage(String title, String body)
      Creates a notification message for use with PushContext.send().
      Parameters:
      title - The notification title.
      body - The notification body text.
      Returns:
      A new Notification.Message instance.
    • createNotificationMessage

      public static Notification.Message createNotificationMessage(String title, String body, String url)
      Creates a notification message with a navigation URL for use with PushContext.send(). Clicking the notification will navigate to the specified URL.
      Parameters:
      title - The notification title.
      body - The notification body text.
      url - The URL to navigate to when the notification is clicked. Both absolute and relative URLs are accepted.
      Returns:
      A new Notification.Message instance.
      Throws:
      IllegalArgumentException - When the URL syntax is invalid.
    • encodeChildren

      public void encodeChildren(FacesContext context) throws IOException
      First check if the SSE endpoint is registered and the web app manifest resource is referenced, then validate and register the channel in SseChannelManager, then render the Notification.init() and Push.init() scripts.
      Overrides:
      encodeChildren in class UIComponentBase
      Throws:
      IllegalStateException - When the SSE endpoint is not registered or the web app manifest resource is not referenced.
      IllegalArgumentException - When the channel name is invalid.
      IOException
    • isStacked

      public boolean isStacked()
      Returns whether notifications should be stacked instead of replaced.
      Returns:
      Whether notifications are stacked.
    • setStacked

      public void setStacked(boolean stacked)
      Sets whether notifications should be stacked instead of replaced. Defaults to false, meaning each new notification replaces the previous one (deduplication by component client ID as tag). When set to true, no tag is set and each notification is displayed independently.
      Parameters:
      stacked - Whether notifications should be stacked.
    • isRequireInteraction

      public boolean isRequireInteraction()
      Returns whether the notification requires interaction to be dismissed.
      Returns:
      Whether the notification requires interaction.
    • setRequireInteraction

      public void setRequireInteraction(boolean requireInteraction)
      Sets whether the notification requires interaction to be dismissed. Defaults to false. Maps to the Notification API requireInteraction option.
      Parameters:
      requireInteraction - Whether the notification requires interaction.
    • isSilent

      public boolean isSilent()
      Returns whether the notification should be silent (no sound/vibration).
      Returns:
      Whether the notification is silent.
    • setSilent

      public void setSilent(boolean silent)
      Sets whether the notification should be silent (no sound/vibration). Defaults to false. Maps to the Notification API silent option.
      Parameters:
      silent - Whether the notification is silent.
    • getIcon

      public String getIcon()
      Returns the notification icon URL.
      Returns:
      The notification icon URL.
    • setIcon

      public void setIcon(String icon)
      Sets the notification icon URL. Maps to the Notification API icon option.
      Parameters:
      icon - The notification icon URL.
    • getOnclick

      public String getOnclick()
      Returns the JavaScript event handler function that is invoked when a notification is clicked.
      Returns:
      The onclick handler.
    • setOnclick

      public void setOnclick(String onclick)
      Sets the JavaScript event handler function that is invoked when a notification is clicked. The function will be invoked with one argument: the CustomEvent with notification details.
      Parameters:
      onclick - The onclick handler.
    • getOnclose

      public String getOnclose()
      Returns the JavaScript event handler function that is invoked when a notification is closed.
      Returns:
      The onclose handler.
    • setOnclose

      public void setOnclose(String onclose)
      Sets the JavaScript event handler function that is invoked when a notification is closed. The function will be invoked with one argument: the CustomEvent with notification details.
      Parameters:
      onclose - The onclose handler.
    • getOnerror

      public String getOnerror()
      Returns the JavaScript event handler function that is invoked when a notification error occurs.
      Returns:
      The onerror handler.
    • setOnerror

      public void setOnerror(String onerror)
      Sets the JavaScript event handler function that is invoked when a notification error occurs. The function will be invoked with one argument: the error event.
      Parameters:
      onerror - The onerror handler.
    • getOnpermissionchange

      public String getOnpermissionchange()
      Returns the JavaScript event handler function that is invoked when the notification permission changes.
      Returns:
      The onpermissionchange handler.
    • setOnpermissionchange

      public void setOnpermissionchange(String onpermissionchange)
      Sets the JavaScript event handler function that is invoked when the notification permission changes. The function will be invoked with one argument: the permission string ("granted", "denied", or "default").
      Parameters:
      onpermissionchange - The onpermissionchange handler.
    • getOnunsupported

      public String getOnunsupported()
      Returns the JavaScript event handler function that is invoked when the Notifications API is not supported.
      Returns:
      The onunsupported handler.
    • setOnunsupported

      public void setOnunsupported(String onunsupported)
      Sets the JavaScript event handler function that is invoked when the Notifications API is not supported or the service worker is not available. The function will be invoked with no arguments.
      Parameters:
      onunsupported - The onunsupported handler.
    • setValueExpression

      public void setValueExpression(String name, ValueExpression binding)
      An override which checks if this isn't been invoked on channel attribute, and if the user attribute is Serializable. Finally it delegates to the super method.
      Overrides:
      setValueExpression in class UIComponent
      Throws:
      IllegalArgumentException - When this value expression is been set on channel attribute, or when the user attribute is not Serializable.
    • getChannel

      public String getChannel()
      Returns the name of the push channel.
      Returns:
      The name of the push channel.
    • setChannel

      public void setChannel(String channel)
      Sets the name of the push channel. It may not be an EL expression and it may only contain alphanumeric characters, hyphens, underscores and periods. All open connections on the same channel will receive the same push message from the server.
      Parameters:
      channel - The name of the push channel.
    • getUser

      public Serializable getUser()
      Returns the user identifier of the push channel.
      Returns:
      The user identifier of the push channel.
    • setUser

      public void setUser(Serializable user)
      Sets the user identifier of the push channel, so that user-targeted push messages can be sent. All open connections on the same channel and user will receive the same push message from the server. It must implement Serializable and preferably have low memory footprint. Suggestion: use #{request.remoteUser} or #{someLoggedInUser.id}.
      Parameters:
      user - The user identifier of the push channel.