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.
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.
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
Notification#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"));
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);
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" />
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 #setStacked(boolean) 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");
// ...
}
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");
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']}" />
| Info | Value |
|---|---|
| Component Type | org.omnifaces.cdi.push.Notification |
| Handler Class | None |
| Renderer Type | None |
| Description | None |
| Name | Required | Type | Description |
|---|---|---|---|
binding | false | jakarta.el.ValueExpression
(must evaluate to jakarta.faces.component.UIComponent)
| The ValueExpression linking this component to a property in a backing bean. |
channel | true | jakarta.el.ValueExpression
(must evaluate to java.lang.String)
| 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. |
icon | false | jakarta.el.ValueExpression
(must evaluate to java.lang.String)
| The notification icon URL. Maps to the Notification API icon option. |
id | false | jakarta.el.ValueExpression
(must evaluate to java.lang.String)
| The component identifier for this component. This value must be unique within the closest parent component that is a naming container. |
onclick | false | jakarta.el.ValueExpression
(must evaluate to java.lang.String)
| 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. |
onclose | false | jakarta.el.ValueExpression
(must evaluate to java.lang.String)
| 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. |
onerror | false | jakarta.el.ValueExpression
(must evaluate to java.lang.String)
| The JavaScript event handler function that is invoked when a notification error occurs. The function will be invoked with one argument: the error event. |
onpermissionchange | false | jakarta.el.ValueExpression
(must evaluate to java.lang.String)
| 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"). |
onunsupported | false | jakarta.el.ValueExpression
(must evaluate to java.lang.String)
| 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. |
rendered | false | jakarta.el.ValueExpression
(must evaluate to boolean)
| Flag indicating whether or not this component should be rendered (during Render Response Phase), or processed on any subsequent form submit. The default value for this property is true. |
requireInteraction | false | jakarta.el.ValueExpression
(must evaluate to boolean)
| Whether the notification requires interaction to be dismissed. Defaults to false. Maps to the
Notification API requireInteraction option. |
silent | false | jakarta.el.ValueExpression
(must evaluate to boolean)
| Whether the notification should be silent (no sound/vibration). Defaults to false. Maps to
the Notification API silent option. |
stacked | false | jakarta.el.ValueExpression
(must evaluate to boolean)
| 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. |
user | false | jakarta.el.ValueExpression
(must evaluate to java.io.Serializable)
| 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}. |
Output generated by Vdldoc View Declaration Language Documentation Generator.