DesktopNotification
DesktopNotification provides a clean API wrapper around the browser's native Notification API, enabling desktop push notifications with proper permission handling, event callbacks, and instance management.
- User permission (click "Request Permission" button below)
- Secure context (HTTPS or localhost)
- User interaction to trigger (cannot auto-show on page load)
- Browser support (not available in all browsers)
Not seeing popups? Notifications may be going to your system notification center (Windows Action Center, macOS Notification Center, etc.). Check your system tray or notification icon.
Key Features
- Browser native desktop notifications
- Automatic permission request handling
- Instance tracking with closeAll() capability
- Full event handler support (onClick, onClose, onError, onShow)
- Persistent notifications with requireInteraction
- Custom icons, badges, and tags
- Silent mode for no-sound notifications
- Graceful browser support detection
When to Use Notifications
- Timer/Alarm Completion: Alert users when countdowns or scheduled events trigger
- Real-time Updates: New messages, comments, or activity notifications
- Task Completion: Background processes, file uploads, long-running operations
- Reminders: Meeting alerts, deadline warnings, scheduled tasks
- System Events: Connection status, errors, important system messages
Basic Usage
// Quick notification (static method)
Domma.elements.notify('Hello', {
body: 'This is a notification!',
icon: '/icon.png'
});
// Instance with full control
const notif = Domma.elements.notification({
title: 'New Message',
body: 'You have 3 unread messages',
requireInteraction: true,
onClick: (event, notificationInstance) => {
console.log('Notification clicked!');
window.focus();
}
});
await notif.show(); // Returns promise
notif.close(); // Close manually
notif.isShown(); // Check state
Quick Start
Show your first desktop notification in seconds. The API automatically handles permission requests.
Simplest Notification
// One-liner for quick notifications
Domma.elements.notify('Hello World!');
// With body text
Domma.elements.notify('Success', {
body: 'Your changes have been saved'
});
Permission Handling
// Check permission status
console.log(Domma.DesktopNotification.permission); // 'default', 'granted', 'denied'
// Request permission manually (optional - auto-requested on first show)
const permission = await Domma.DesktopNotification.requestPermission();
if (permission === 'granted') {
Domma.elements.notify('Permission Granted!');
}
Step-by-Step Tutorial
Learn how to create notifications with full control over behaviour and appearance.
Step 1: Create Notification Instance
const notification = Domma.elements.notification({
title: 'Meeting Reminder',
body: 'Team standup in 5 minutes',
icon: '/assets/calendar-icon.png',
badge: '/assets/badge.png',
tag: 'meeting-reminder', // Reuse tag to replace existing
requireInteraction: true // Stays until user dismisses
});
Step 2: Add Event Handlers
const notification = Domma.elements.notification({
title: 'New Message',
body: 'Click to view',
onClick: (event, notificationInstance) => {
console.log('User clicked notification');
window.focus();
// Navigate to messages page
window.location.href = '/messages';
},
onClose: (event, notificationInstance) => {
console.log('Notification closed');
},
onShow: (event, notificationInstance) => {
console.log('Notification shown');
},
onError: (error) => {
console.error('Notification error:', error);
}
});
Step 3: Show and Control
// Show the notification (async)
await notification.show();
// Check if shown
if (notification.isShown()) {
console.log('Notification is visible');
}
// Close programmatically
setTimeout(() => {
notification.close();
}, 5000);
Real-World Examples
1. Success/Error Notifications
// Success notification
function notifySuccess(message) {
Domma.elements.notify('Success', {
body: message,
icon: '/icons/success.png',
tag: 'success'
});
}
// Error notification
function notifyError(message) {
Domma.elements.notify('Error', {
body: message,
icon: '/icons/error.png',
tag: 'error',
requireInteraction: true // Don't auto-dismiss errors
});
}
// Usage
notifySuccess('Profile updated successfully');
notifyError('Failed to upload file');
2. Integration with Timer
// Notify when timer completes
const timer = Domma.elements.timer('#timer', {
duration: 300000, // 5 minutes
onComplete: () => {
Domma.elements.notify('Timer Complete!', {
body: 'Your 5-minute timer has finished',
requireInteraction: true,
onClick: () => window.focus()
});
}
});
3. Multiple Notifications with Tracking
// Create multiple notifications
const notifications = [];
for (let i = 0; i < 3; i++) {
const notif = Domma.elements.notification({
title: `Notification ${i + 1}`,
body: `Message content ${i + 1}`,
tag: `notification-${i}` // Unique tag
});
notifications.push(notif);
notif.show();
}
// Close all at once
Domma.DesktopNotification.closeAll();
// Or close specific one
notifications[0].close();
4. Silent Notifications
// Silent notification (no sound)
Domma.elements.notify('Background Task Complete', {
body: 'File has been processed',
silent: true, // No notification sound
tag: 'background-task'
});
5. Hybrid: Desktop with Toast Fallback (Recommended)
// Smart notification that always shows something
async function smartNotify(title, options = {}) {
// Try desktop notification first
if (Domma.DesktopNotification.isSupported &&
Domma.DesktopNotification.permission === 'granted') {
Domma.elements.notify(title, {
body: options.body,
...options.notificationOptions
});
return 'desktop';
}
// Fallback to toast (always visible in page)
const message = options.body || title;
const type = options.type || 'info';
Domma.elements.toast[type](message, {
duration: options.duration || 5000,
position: 'top-right'
});
return 'toast';
}
// Usage - always shows something!
await smartNotify('Task Complete', {
body: 'Your file has been uploaded',
type: 'success'
});
Best Practices
✅ Do's
- Use hybrid approach with Toast fallback - Always provide visual feedback (see example above)
- Request permission at appropriate time - Ask when user performs related action, not on page load
- Provide clear, concise messages - Title should be 1-3 words, body should be one sentence
- Use requireInteraction for important alerts - Errors, critical warnings, time-sensitive actions
- Add onClick handlers for actionable notifications - Navigate user to relevant content
- Use unique tags for related notifications - Replace previous notification of same type
- Check browser support - Use DesktopNotification.isSupported before showing
- Understand system behavior - Notifications may go to system notification center, not always popup
❌ Don'ts
- Don't spam notifications - Batch updates, use debouncing for rapid events
- Don't request permission on page load - Users will likely deny without context
- Don't rely solely on notifications - They may be blocked or unavailable
- Don't use for every action - Reserve for important, time-sensitive events
- Don't use long messages - Keep title + body under 100 characters total
- Don't forget to close - Use tags to auto-replace or close programmatically
Permission UX Pattern
// Good: Explain before requesting
async function setupNotifications() {
// Show in-app prompt first
const userWantsNotifications = await showInAppPrompt(
'Enable notifications to get alerts for timer completion?'
);
if (userWantsNotifications) {
const permission = await Domma.DesktopNotification.requestPermission();
if (permission === 'granted') {
// Show confirmation
Domma.elements.notify('Notifications Enabled!');
} else {
// Show fallback option
Domma.elements.toast('Notifications blocked. You can enable them in settings.');
}
}
}
Error Handling Pattern
async function safeNotify(title, options = {}) {
// Check support
if (!Domma.DesktopNotification.isSupported) {
console.warn('Notifications not supported');
// Fallback to toast or banner
Domma.elements.toast(title);
return null;
}
// Check permission
if (Domma.DesktopNotification.permission !== 'granted') {
console.warn('Notification permission not granted');
Domma.elements.toast(title);
return null;
}
// Show notification with error handler
const notif = Domma.elements.notification({
title,
...options,
onError: (error) => {
console.error('Notification failed:', error);
Domma.elements.toast(title); // Fallback
}
});
await notif.show();
return notif;
}
Complete API Reference
Factory Methods
// Create notification instance elements.notification(options) // Quick notification (static method) elements.notify(title, options)
Options
| Option | Type | Default | Description |
|---|---|---|---|
title |
string | 'Notification' | Notification title (bold text) |
body |
string | '' | Notification body text |
icon |
string | null | URL to icon image |
badge |
string | null | URL to badge image (Android) |
tag |
string | null | Unique ID - replaces existing with same tag |
requireInteraction |
boolean | false | Stays visible until user dismisses |
silent |
boolean | false | No notification sound |
data |
any | null | Custom data attached to notification |
onClick |
function | null | Callback when notification is clicked |
onClose |
function | null | Callback when notification is closed |
onError |
function | null | Callback on error |
onShow |
function | null | Callback when notification is shown |
Instance Methods
// Show notification (returns Promise) await notification.show() // Close notification notification.close() // Check if shown notification.isShown() // Returns boolean
Static Methods
// Request permission (returns Promise) await DesktopNotification.requestPermission() // Quick notification DesktopNotification.notify(title, options) // Close all active notifications DesktopNotification.closeAll()
Static Properties
// Current permission state DesktopNotification.permission // 'default', 'granted', 'denied' // Browser support check DesktopNotification.isSupported // boolean
Declarative Configuration
While notifications are typically shown programmatically, you can use the config engine to set up notification triggers.
Trigger Notification on Click
$.setup({
'#notify-button': {
events: {
click: (e, $el) => {
Domma.elements.notify('Button Clicked', {
body: 'You clicked the notification button'
});
}
}
}
});
Form Submission Notification
$.setup({
'#contact-form': {
events: {
submit: async (e, $el) => {
e.preventDefault();
// Submit form
const response = await fetch('/api/contact', {
method: 'POST',
body: new FormData(e.target)
});
if (response.ok) {
Domma.elements.notify('Message Sent!', {
body: 'We will get back to you soon',
icon: '/icons/success.png'
});
} else {
Domma.elements.notify('Error', {
body: 'Failed to send message',
requireInteraction: true
});
}
}
}
}
});
Related Components
DesktopNotification works well with other Domma components for complete user feedback systems.
When to Use Each
- DesktopNotification: System-level alerts, background task completion, urgent updates even when tab inactive
- Toast: Quick in-app feedback, success confirmations, non-critical info
- Modal: Requires immediate user decision or attention, blocks interaction
- Alert Banner: Persistent warnings, system status, non-blocking info