Adding Features: Notifications, System Tray, and More
Congratulations! You've made it this far, and your Electron app is looking solid. Now, let's give it that extra polish with some pro-level features things like notifications and system tray icons that users expect from top-tier desktop applications.
These may seem like minor details, but they enhance the overall user experience, making your app more engaging, practical, and even more fun to use. Think of it like adding the final touches to a dish that takes it from "good" to "wow!"
Step 1: Setting Up System Notifications
Notifications are a great way to keep users informed about what’s happening in your app, even when they’re not actively using it. You’ve seen them on your computer for everything from chat messages to software updates, and adding them to your Electron app is pretty easy.
Why Notifications Matter:
- Engagement: They remind users about important events or updates without them needing to open the app.
- Feedback: They let users know when actions (like file uploads or processing tasks) are complete.
How to Create a Notification in Electron
Electron uses the standard HTML5 Notification API, which means if you’ve ever worked with notifications in web development, you’re in familiar territory. Let’s walk through how to add a simple notification to your app.
-
Request Notification Permission Notifications need the user's permission to display, so it’s good practice to ask for that early in your app. Here’s how you can do that:
if (Notification.permission !== 'granted') { Notification.requestPermission().then(permission => { if (permission === 'granted') { new Notification('Thanks for allowing notifications!'); } }); }
This prompts the user to grant permission for notifications. If granted, we immediately show a "thank you" notification to confirm it worked.
-
Create a Basic Notification
Once permission is granted, creating notifications is a breeze. Here’s a quick example:
const notifyUser = () => { new Notification('Hello!', { body: 'This is your first Electron notification.', icon: 'path/to/icon.png' // Optional: you can add an icon. }); };
That’s it! Now, every time the
notifyUser()
function is called, a notification will pop up on the user's desktop.
Enhancing Notifications with Interactivity
You can make your notifications more interactive by adding buttons or even letting users click them to open the app or perform specific actions.
-
Adding a Click Event
To make a notification clickable, you can add an event listener like this:
const notifyUser = () => { const notification = new Notification('You’ve got mail!', { body: 'Click here to open the app.', }); notification.onclick = () => { // Focus or open the app window when clicked mainWindow.show(); }; };
This is useful if you want to notify users of something important and let them jump straight back into the app by clicking on the notification.
-
Adding Buttons to Notifications
For more advanced interactions, you can add action buttons (though this only works on some platforms). Here’s an example:
const notifyUser = () => { const notification = new Notification('Reminder', { body: 'Your meeting starts in 5 minutes.', actions: [ { action: 'snooze', title: 'Snooze' }, { action: 'dismiss', title: 'Dismiss' } ] }); notification.onclick = (event) => { if (event.action === 'snooze') { console.log('Snoozed!'); } else if (event.action === 'dismiss') { console.log('Dismissed!'); } }; };
This example adds two buttons—Snooze and Dismiss—to the notification. The click events handle what happens when each button is pressed.
Step 2: Minimizing Your App to the System Tray
Another cool feature you can add is the ability to minimize your app to the system tray. This is especially useful for apps that need to run in the background, like chat apps, music players, or download managers.
The system tray is the little icon area in the bottom-right corner (Windows) or top-right (Mac) of your desktop. By adding a tray icon, users can quickly access your app without it cluttering up their taskbar or dock.
Creating a Tray Icon in Electron
Setting up a tray icon in Electron is super simple. You’ll use the Tray module to add an icon and give users options to interact with it.
-
Add a Tray Icon
First, you need an image to serve as your tray icon (usually a small, 16x16 or 32x32 PNG). Then, add the following to your main process (
main.js
):const { Tray, Menu } = require('electron'); let tray = null; app.on('ready', () => { tray = new Tray('path/to/icon.png'); // Your tray icon image const contextMenu = Menu.buildFromTemplate([ { label: 'Show App', click: () => mainWindow.show() }, { label: 'Quit', click: () => app.quit() } ]); tray.setToolTip('My Electron App'); // Hover text tray.setContextMenu(contextMenu); // Right-click menu });
In this example, the tray icon has a right-click menu with options to show the app or quit. You can customize the context menu however you like.
-
Minimize to Tray
You might want to minimize the app to the tray when the user closes it, instead of quitting it entirely. Here’s how to do that:
mainWindow.on('close', (event) => { if (!app.isQuitting) { event.preventDefault(); mainWindow.hide(); // Minimize to tray instead of closing } });
Now, when the user tries to close the app, it hides to the tray instead.
Step 3: Advanced Tray Features
Once you have the basics working, you can add some extra flair to your tray icon to make it even more functional and engaging.
-
Dynamic Icons
You can change the tray icon based on your app’s state. For example, a music player might switch between "playing" and "paused" icons:
let playing = false; const updateTrayIcon = () => { if (playing) { tray.setImage('path/to/playing-icon.png'); } else { tray.setImage('path/to/paused-icon.png'); } }; tray.on('click', () => { playing = !playing; updateTrayIcon(); });
-
Tray Notifications
You can also use tray icons to notify users of important events. For example, flashing the tray icon when a message arrives:
tray.setImage('path/to/flash-icon.png'); // Flashing icon setTimeout(() => { tray.setImage('path/to/default-icon.png'); // Revert back after a few seconds }, 3000);
Step 4: Implementing Other Desktop Features
Now that you’ve mastered notifications and the system tray, here are a few more neat tricks to make your Electron app feel truly native and polished:
-
Context Menus Everywhere
You can add right-click menus to pretty much any part of your app using the Menu module. For example, adding a context menu to your app’s window:
const { Menu } = require('electron'); const contextMenu = Menu.buildFromTemplate([ { label: 'Reload', role: 'reload' }, { label: 'Toggle DevTools', role: 'toggledevtools' } ]); mainWindow.webContents.on('context-menu', () => { contextMenu.popup(); });
Now, when the user right-clicks anywhere in your app’s window, the custom menu will appear.
-
Global Keyboard Shortcuts
Want to give your users quick access to certain features, even when the app isn’t focused? Add global keyboard shortcuts! For example, a music player might use a global shortcut to play or pause tracks:
const { globalShortcut } = require('electron'); app.on('ready', () => { globalShortcut.register('CommandOrControl+Shift+P', () => { console.log('Play/Pause triggered!'); }); });
This shortcut works even if the app is running in the background.
Wrapping Up
Adding system notifications, a tray icon, and other desktop features may seem like small details, but they can make a huge difference in how polished and professional your app feels. These features help users interact with your app more effectively, whether it’s running in the foreground or background.
By now, you’ve learned how to:
- Create engaging system notifications.
- Minimize your app to the system tray.
- Add useful desktop features like context menus and global keyboard shortcuts.
These are the kinds of features that can set your app apart and give users that extra bit of convenience that keeps them coming back.
Keep experimenting and adding new features to your Electron app, and don’t be afraid to get creative with how you enhance the user experience. You’ve come a long way, and your app is on its way to feeling a professional product.