The tray icon
The tray is the area near the clock on the Windows taskbar, or the right side of the menu bar on macOS. An icon there lets the app run in the background: the window is hidden, and a note is one click away. The icon is created with the Tray class in the main process.
The icon image
Put an assets/tray.png file of 16 by 16 pixels in the project (you can add a 32 by 32 tray@2x.png for high-density screens). Electron picks the right size itself.
| System | Recommended format |
|---|---|
| Windows | .ico or .png |
| macOS | A black-and-transparent .png whose name ends in Template, e.g. trayTemplate.png |
| Linux | .png |
On macOS an image with Template in its name is recoloured automatically for light and dark themes.
Creating the icon
// main.js
const { app, BrowserWindow, Tray, Menu } = require('electron');
const path = require('node:path');
let tray = null;
app.whenReady().then(() => {
tray = new Tray(path.join(__dirname, 'assets', 'tray.png'));
tray.setToolTip('Notes');
createWindow();
});After startup the icon appears in the tray. Hovering over it shows the "Notes" tooltip.
The icon menu
// main.js
tray.setContextMenu(Menu.buildFromTemplate([
{ label: 'Show', click: () => win.show() },
{ label: 'New note', click: () => {
win.show();
win.webContents.send('menu:new-note');
} },
{ type: 'separator' },
{ role: 'quit' },
]));Here win is the main window kept in a module-level variable. On Windows the menu opens with a right click, on macOS with any click on the icon. "New note" uses the same channel as the app menu.
Hiding to the tray
To make the close button hide the window instead of quitting, intercept the close event:
// main.js
let isQuitting = false;
app.on('before-quit', () => {
isQuitting = true;
});
win.on('close', (event) => {
if (!isQuitting) {
event.preventDefault();
win.hide();
}
});event.preventDefault() cancels the close, and the window is just hidden. When the user quits through the Quit item, before-quit fires first, the flag becomes true, and the window really closes.
Clicking the icon
// main.js
tray.on('click', () => {
if (win.isVisible()) {
win.hide();
} else {
win.show();
}
});On Windows a left click on the icon shows and hides the window.
Common mistake
If you create the icon in a local variable, such as const tray = new Tray(...) inside a function, it disappears after a while: the garbage collector removes an object nothing refers to. Keep the icon in a module-level variable, like let tray in the example.