Custom Notifications in ElectronJS - GeeksforGeeks

11 May, 2020
ElectronJS is an Open Source Framework used for building Cross-Platform native desktop applications using web technologies such as HTML, CSS, and JavaScript which are capable of running on Windows, macOS, and Linux operating systems. It combines the Chromium engine and NodeJS into a Single Runtime.
Electron at its core is a NodeJS application having capabilities to interact with the native OS environment such as File System, System Tray etc. For creating interactive native OS applications Electron needs to integrate itself with OS functionalities. One such crucial functionality is Desktop Notifications. All three operating systems have provisions for sending Desktop Notifications. Electron provides the built-in Notification Module which allows the application to send Custom Notifications, using the operating systems native notification APIs to display it. This tutorial will demonstrate how to create Custom Desktop Notifications using the Notification Module.
We assume that you are familiar with the prerequisites as covered in the above-mentioned link. For Electron to work, node and npm need to be pre-installed in the system.
Notifications In Electron: The Notification Module is a part of the Main Process. To import and use the Notification Module in the Renderer Process, we can use the Remote Module provided by Electron. In this tutorial, we will also be using Electron Remote. For more details on the Remote Module, Refer this link.
Project Structure:Example: We will start by building the basic Electron Application by following the given steps.Step 1: Navigate to an Empty Directory to setup the project, and run the following command,npm initTo generate the package.json file. Install Electron using npm if it is not installed.npm install electron --save-devThis command will also create the package-lock.json file and install the required node_modules dependencies. Once Electron has been successfully installed, Open the package.json file and perform the necessary changes under the “scripts” key.package.json:{
  "name": "electron-notification",
  "version": "1.0.0",
  "description": "Custom notification in Electron",
  "main": "main.js",
  "scripts": {
    "start": "electron"
  },
  "keywords": [
    "electron"
  ],
  "author": "Radhesh Khanna",
  "license": "ISC",
  "dependencies": {
    "electron": "^8.2.5"
  }
}
Step 2: Create a main.js file according to the project structure. This file is the Main Process and acts as an entry point into the application. Copy the Boilerplate code for the main.js file as given in the following link. We will modify the code to suit our project needs.main.js:const { app, BrowserWindow } = require('electron')  function createWindow() {  // Create the browser window.  const win = new BrowserWindow({    width: 800,    height: 600,    webPreferences: {      nodeIntegration: true    }  })    // Load the index.html of the app.  win.loadFile('src/index.html')    // Open the DevTools.  win.webContents.openDevTools()}  // This method will be called when Electron has finished// initialization and is ready to create browser windows.// Some APIs can only be used after this event occurs.app.whenReady().then(createWindow)  // Quit when all windows are closed.app.on('window-all-closed', () => {  // On macOS it is common for applications and their  // menu bar to stay active until the user quits   // explicitly with Cmd + Q  if (process.platform !== 'darwin') {    app.quit()  }})  app.on('activate', () => {  // On macOS it's common to re-create a window in the  // app when the  dock icon is clicked and there are  // no other windows open.  if (BrowserWindow.getAllWindows().length === 0) {    createWindow()  }})  // In this file, you can include the rest of your app's// specific main process code. You can also put them in // separate files and require them here.Step 3: Create the index.html file within the src directory. We will also copy the boilerplate code for the index.html file from the above-mentioned link. We will modify the code to suit our project needs.index.html:<!DOCTYPE html><html>  <head>    <meta charset="UTF-8">    <title>Hello World!</title>        <!-- https://electronjs.org/docs/tutorial                      /security#csp-meta-tag -->    <meta http-equiv="Content-Security-Policy"          content="script-src 'self' 'unsafe-inline';" /></head>  <body>    <h1>Hello World!</h1> We are using node    <script>        document.write(process.versions.node)    </script>, Chrome    <script>        document.write(process.versions.chrome)    </script>, and Electron    <script>        document.write(process.versions.electron)    </script>.      <!-- Adding Individual Renderer Process JS File -->    <script src="index.js"></script></body>  </html>Output: At this point, our basic Electron Application is set up. To launch the Electron Application, run the Command:npm startNotification Options: Now we will create a Custom Desktop Notification on a Windows Machine. The Notification Module provides certain Instance Events, Instance Methods, and Options which are Operating System specific. If a property that is incompatible with the native OS is used, it is Simple Ignored. A detailed list of the same is provided below.title: String Supported by all OS. The Title of the Notification shown at top of Notification Windowsubtitle: String (Optional) Supported by macOS only. A Subtitle of the Notification. Shown Below the Titlebody: String Supported by all OS. The Body of the Notification Windowsilent: Boolean (Optional) Supported by all OS. Whether or not to omit OS Notification Sound on displaying the notificationicon: String (Optional) Supported by all OS. An Icon to display in the Notification Window. For the purpose of this tutorial, used a PNG image of the Electron logo saved in the ‘assets’ folderhasReply: Boolean (Optional) Supported by macOS only. To display an Inline Reply Option to the Notification windowreplyPlaceholder: String (Optional) Supported by macOS only. The Placeholder for the ‘hasReply’ input fieldurgency: String (Optional) Supported by Linux Only. The urgency of the Notification. Values can be ‘normal’, ‘critical’, or ‘low’.closeButtonText: String (Optional) Supported by macOS only. A Custom Title for the Close Button of the NotificationtimeoutType: String (Optional) Supported in Windows and Linux operating Systems. The Timeout Duration of the Notification. Values can be ‘default’ or ‘never’. As of Electron 8.0+, there is a bug associated with this property. Setting the value as ‘never’, the notification should only disappear on manual intervention by the user. However, This is not the case. Irrespective of the value, the notification will disappear on its own. You can follow the bug tracking here.actions: Object (Optional) Supported by macOS only. Actions to add to the Notification. It is an Array of Objects. Every Object consists of ‘type’ and ‘text’. There are certain limitations associated with using this property. In the case of multiple actions defined, only the first one is used. If multiple actions are provided then they will be listed as additional actions, i.e. displayed when the mouse is active over the first action button. This case is also incompatible with hasReply property and will be ignored if hasReply: true.For a detailed explanation, Refer this link.sound: String (Optional) Supported by macOS only. Sound File to play when the Notification is displayed. Any of the default sounds present in macOS can also be used in addition to a custom sound file. The sound file needs to be present within the app bundle or any of the following locations that are mentioned in this link. In this tutorial the custom sound file is present within the assets folder as sound.mp3The Notification Module also provides us with a Static Method,Notification.isSupported(). Returns a Boolean value stating whether Notifications are Supported in the Current System or not. In the index.html file, add the following code before the script tag.index.html:<br><br>    <strong>     Trigger Custom Notifications in Electron    </strong>    <button id="trigger">     Trigger Custom Notification    </button>Output:The Trigger Custom Notification Button does not have any functionality associated with it. We will add an EventListener to the button to trigger the Custom Notification. We will also add EventListener to the Notification object. Create the index.js file following the project Structure and perform the following changes.index.js:const electron = require('electron');const path = require('path')  // Importing the Notification Module from Electron,// Since it is a Part of the Main Process, Using the// Remote Module to Import it in Renderer Processconst Notification = electron.remote.Notification;  var button = document.getElementById('trigger');  const options = {    title: 'Custom Notification',    subtitle: 'Subtitle of the Notification',    body: 'Body of Custom Notification',    silent: false,    icon: path.join(__dirname, '../assets/image.png'),    hasReply: true,      timeoutType: 'never',     replyPlaceholder: 'Reply Here',    sound: path.join(__dirname, '../assets/sound.mp3'),    urgency: 'critical'     closeButtonText: 'Close Button'    actions: [ {        type: 'button',        text: 'Show Button'    }]}  // Instantiating a new Notifications Object// with custom Optionsconst customNotification = new Notification(options);   button.addEventListener('click', function (event) {    console.log(Notification.isSupported());      customNotification.show();    // customNotification.close();});  // Instance Events for the new Notification ObjectcustomNotification.addListener('click', () => {    console.log('Notification is Clicked');});  customNotification.addListener('show', () => {    console.log('Notification is shown');});  customNotification.addListener('close', () => {    console.log('Notification is Automatically Closed')});customNotification.show() Instance Method to immediately show the Notification to the user. In case the Notification has been shown, dismisses the previous one and creates a new Notification with identical Options.customNotification.close() Instance Method to dismiss the Notification.Event: ‘click’ Event is Emitted, when user clicks on the Notification.Event: ‘show’ Event is Emitted, when notification is shown to the user.Event: ‘close’ Event is Emitted, when Notification is Closed. Not guaranteed to be emitted every time. Notification will automatically close irrespective of ‘timeoutType’ property.Output:Instance events: Notification Module also provides two more Instance events which are supported by macOS only.// Emitted when user clicks the reply button from // 'hasReply: true' propertycustomNotification.addListener('reply', (event, reply) => {    console.log('Replied String is - ', reply);});  // Emitted when the user clicks on any one action // defined in the actions:[{}] propertycustomNotification.addListener('action', (event, index) => {    console.log('Index of the action clicked is - ', index);});Instance Properties: Electron Notification Module also Supports Instance Properties which can be set to the Notification Object. They can be used instead of Options and can also change pre-defined options when triggering Custom Notifications. A detailed list is given below.customNotification.title = 'Title has been Changed';  // Supported in macOScustomNotification.subtitle = 'Subtitle of the Notification';    customNotification.body = 'Body has been changed';  // Supported in macOScustomNotification.closeButtonText = 'Close Button'    // Supported in macOScustomNotification.hasReply = true;  // Supported in macOScustomNotification.replyPlaceholder = 'Reply Placeholder';   customNotification.silent = false;  // Supported in LinuxcustomNotification.urgency = 'low';  // Supported in Windows and Linux OS // This is a bug, as described above.customNotification.timeoutType= 'default';
Example: We will start by building the basic Electron Application by following the given steps.
Step 1: Navigate to an Empty Directory to setup the project, and run the following command,npm initTo generate the package.json file. Install Electron using npm if it is not installed.npm install electron --save-devThis command will also create the package-lock.json file and install the required node_modules dependencies. Once Electron has been successfully installed, Open the package.json file and perform the necessary changes under the “scripts” key.package.json:{
  "name": "electron-notification",
  "version": "1.0.0",
  "description": "Custom notification in Electron",
  "main": "main.js",
  "scripts": {
    "start": "electron"
  },
  "keywords": [
    "electron"
  ],
  "author": "Radhesh Khanna",
  "license": "ISC",
  "dependencies": {
    "electron": "^8.2.5"
  }
}

npm init
To generate the package.json file. Install Electron using npm if it is not installed.
npm install electron --save-dev
This command will also create the package-lock.json file and install the required node_modules dependencies. Once Electron has been successfully installed, Open the package.json file and perform the necessary changes under the “scripts” key.
package.json:
{
  "name": "electron-notification",
  "version": "1.0.0",
  "description": "Custom notification in Electron",
  "main": "main.js",
  "scripts": {
    "start": "electron"
  },
  "keywords": [
    "electron"
  ],
  "author": "Radhesh Khanna",
  "license": "ISC",
  "dependencies": {
    "electron": "^8.2.5"
  }
}

Step 2: Create a main.js file according to the project structure. This file is the Main Process and acts as an entry point into the application. Copy the Boilerplate code for the main.js file as given in the following link. We will modify the code to suit our project needs.main.js:const { app, BrowserWindow } = require('electron')  function createWindow() {  // Create the browser window.  const win = new BrowserWindow({    width: 800,    height: 600,    webPreferences: {      nodeIntegration: true    }  })    // Load the index.html of the app.  win.loadFile('src/index.html')    // Open the DevTools.  win.webContents.openDevTools()}  // This method will be called when Electron has finished// initialization and is ready to create browser windows.// Some APIs can only be used after this event occurs.app.whenReady().then(createWindow)  // Quit when all windows are closed.app.on('window-all-closed', () => {  // On macOS it is common for applications and their  // menu bar to stay active until the user quits   // explicitly with Cmd + Q  if (process.platform !== 'darwin') {    app.quit()  }})  app.on('activate', () => {  // On macOS it's common to re-create a window in the  // app when the  dock icon is clicked and there are  // no other windows open.  if (BrowserWindow.getAllWindows().length === 0) {    createWindow()  }})  // In this file, you can include the rest of your app's// specific main process code. You can also put them in // separate files and require them here.
main.js:
const { app, BrowserWindow } = require('electron')  function createWindow() {  // Create the browser window.  const win = new BrowserWindow({    width: 800,    height: 600,    webPreferences: {      nodeIntegration: true    }  })    // Load the index.html of the app.  win.loadFile('src/index.html')    // Open the DevTools.  win.webContents.openDevTools()}  // This method will be called when Electron has finished// initialization and is ready to create browser windows.// Some APIs can only be used after this event occurs.app.whenReady().then(createWindow)  // Quit when all windows are closed.app.on('window-all-closed', () => {  // On macOS it is common for applications and their  // menu bar to stay active until the user quits   // explicitly with Cmd + Q  if (process.platform !== 'darwin') {    app.quit()  }})  app.on('activate', () => {  // On macOS it's common to re-create a window in the  // app when the  dock icon is clicked and there are  // no other windows open.  if (BrowserWindow.getAllWindows().length === 0) {    createWindow()  }})  // In this file, you can include the rest of your app's// specific main process code. You can also put them in // separate files and require them here.
Step 3: Create the index.html file within the src directory. We will also copy the boilerplate code for the index.html file from the above-mentioned link. We will modify the code to suit our project needs.index.html:<!DOCTYPE html><html>  <head>    <meta charset="UTF-8">    <title>Hello World!</title>        <!-- https://electronjs.org/docs/tutorial                      /security#csp-meta-tag -->    <meta http-equiv="Content-Security-Policy"          content="script-src 'self' 'unsafe-inline';" /></head>  <body>    <h1>Hello World!</h1> We are using node    <script>        document.write(process.versions.node)    </script>, Chrome    <script>        document.write(process.versions.chrome)    </script>, and Electron    <script>        document.write(process.versions.electron)    </script>.      <!-- Adding Individual Renderer Process JS File -->    <script src="index.js"></script></body>  </html>
index.html:
<!DOCTYPE html><html>  <head>    <meta charset="UTF-8">    <title>Hello World!</title>        <!-- https://electronjs.org/docs/tutorial                      /security#csp-meta-tag -->    <meta http-equiv="Content-Security-Policy"          content="script-src 'self' 'unsafe-inline';" /></head>  <body>    <h1>Hello World!</h1> We are using node    <script>        document.write(process.versions.node)    </script>, Chrome    <script>        document.write(process.versions.chrome)    </script>, and Electron    <script>        document.write(process.versions.electron)    </script>.      <!-- Adding Individual Renderer Process JS File -->    <script src="index.js"></script></body>  </html>
Output: At this point, our basic Electron Application is set up. To launch the Electron Application, run the Command:npm start
npm start
Notification Options: Now we will create a Custom Desktop Notification on a Windows Machine. The Notification Module provides certain Instance Events, Instance Methods, and Options which are Operating System specific. If a property that is incompatible with the native OS is used, it is Simple Ignored. A detailed list of the same is provided below.
title: String Supported by all OS. The Title of the Notification shown at top of Notification Window
subtitle: String (Optional) Supported by macOS only. A Subtitle of the Notification. Shown Below the Title
body: String Supported by all OS. The Body of the Notification Window
silent: Boolean (Optional) Supported by all OS. Whether or not to omit OS Notification Sound on displaying the notification
icon: String (Optional) Supported by all OS. An Icon to display in the Notification Window. For the purpose of this tutorial, used a PNG image of the Electron logo saved in the ‘assets’ folder
hasReply: Boolean (Optional) Supported by macOS only. To display an Inline Reply Option to the Notification window
replyPlaceholder: String (Optional) Supported by macOS only. The Placeholder for the ‘hasReply’ input field
urgency: String (Optional) Supported by Linux Only. The urgency of the Notification. Values can be ‘normal’, ‘critical’, or ‘low’.
closeButtonText: String (Optional) Supported by macOS only. A Custom Title for the Close Button of the Notification
timeoutType: String (Optional) Supported in Windows and Linux operating Systems. The Timeout Duration of the Notification. Values can be ‘default’ or ‘never’. As of Electron 8.0+, there is a bug associated with this property. Setting the value as ‘never’, the notification should only disappear on manual intervention by the user. However, This is not the case. Irrespective of the value, the notification will disappear on its own. You can follow the bug tracking here.
actions: Object (Optional) Supported by macOS only. Actions to add to the Notification. It is an Array of Objects. Every Object consists of ‘type’ and ‘text’. There are certain limitations associated with using this property. In the case of multiple actions defined, only the first one is used. If multiple actions are provided then they will be listed as additional actions, i.e. displayed when the mouse is active over the first action button. This case is also incompatible with hasReply property and will be ignored if hasReply: true.For a detailed explanation, Refer this link.
sound: String (Optional) Supported by macOS only. Sound File to play when the Notification is displayed. Any of the default sounds present in macOS can also be used in addition to a custom sound file. The sound file needs to be present within the app bundle or any of the following locations that are mentioned in this link. In this tutorial the custom sound file is present within the assets folder as sound.mp3
The Notification Module also provides us with a Static Method,Notification.isSupported(). Returns a Boolean value stating whether Notifications are Supported in the Current System or not. In the index.html file, add the following code before the script tag.
index.html:<br><br>    <strong>     Trigger Custom Notifications in Electron    </strong>    <button id="trigger">     Trigger Custom Notification    </button>
<br><br>    <strong>     Trigger Custom Notifications in Electron    </strong>    <button id="trigger">     Trigger Custom Notification    </button>
Output:
The Trigger Custom Notification Button does not have any functionality associated with it. We will add an EventListener to the button to trigger the Custom Notification. We will also add EventListener to the Notification object. Create the index.js file following the project Structure and perform the following changes.
index.js:const electron = require('electron');const path = require('path')  // Importing the Notification Module from Electron,// Since it is a Part of the Main Process, Using the// Remote Module to Import it in Renderer Processconst Notification = electron.remote.Notification;  var button = document.getElementById('trigger');  const options = {    title: 'Custom Notification',    subtitle: 'Subtitle of the Notification',    body: 'Body of Custom Notification',    silent: false,    icon: path.join(__dirname, '../assets/image.png'),    hasReply: true,      timeoutType: 'never',     replyPlaceholder: 'Reply Here',    sound: path.join(__dirname, '../assets/sound.mp3'),    urgency: 'critical'     closeButtonText: 'Close Button'    actions: [ {        type: 'button',        text: 'Show Button'    }]}  // Instantiating a new Notifications Object// with custom Optionsconst customNotification = new Notification(options);   button.addEventListener('click', function (event) {    console.log(Notification.isSupported());      customNotification.show();    // customNotification.close();});  // Instance Events for the new Notification ObjectcustomNotification.addListener('click', () => {    console.log('Notification is Clicked');});  customNotification.addListener('show', () => {    console.log('Notification is shown');});  customNotification.addListener('close', () => {    console.log('Notification is Automatically Closed')});
const electron = require('electron');const path = require('path')  // Importing the Notification Module from Electron,// Since it is a Part of the Main Process, Using the// Remote Module to Import it in Renderer Processconst Notification = electron.remote.Notification;  var button = document.getElementById('trigger');  const options = {    title: 'Custom Notification',    subtitle: 'Subtitle of the Notification',    body: 'Body of Custom Notification',    silent: false,    icon: path.join(__dirname, '../assets/image.png'),    hasReply: true,      timeoutType: 'never',     replyPlaceholder: 'Reply Here',    sound: path.join(__dirname, '../assets/sound.mp3'),    urgency: 'critical'     closeButtonText: 'Close Button'    actions: [ {        type: 'button',        text: 'Show Button'    }]}  // Instantiating a new Notifications Object// with custom Optionsconst customNotification = new Notification(options);   button.addEventListener('click', function (event) {    console.log(Notification.isSupported());      customNotification.show();    // customNotification.close();});  // Instance Events for the new Notification ObjectcustomNotification.addListener('click', () => {    console.log('Notification is Clicked');});  customNotification.addListener('show', () => {    console.log('Notification is shown');});  customNotification.addListener('close', () => {    console.log('Notification is Automatically Closed')});
customNotification.show() Instance Method to immediately show the Notification to the user. In case the Notification has been shown, dismisses the previous one and creates a new Notification with identical Options.
customNotification.close() Instance Method to dismiss the Notification.
Event: ‘click’ Event is Emitted, when user clicks on the Notification.
Event: ‘show’ Event is Emitted, when notification is shown to the user.
Event: ‘close’ Event is Emitted, when Notification is Closed. Not guaranteed to be emitted every time. Notification will automatically close irrespective of ‘timeoutType’ property.
Output:
Instance events: Notification Module also provides two more Instance events which are supported by macOS only.
// Emitted when user clicks the reply button from // 'hasReply: true' propertycustomNotification.addListener('reply', (event, reply) => {    console.log('Replied String is - ', reply);});  // Emitted when the user clicks on any one action // defined in the actions:[{}] propertycustomNotification.addListener('action', (event, index) => {    console.log('Index of the action clicked is - ', index);});
Instance Properties: Electron Notification Module also Supports Instance Properties which can be set to the Notification Object. They can be used instead of Options and can also change pre-defined options when triggering Custom Notifications. A detailed list is given below.
customNotification.title = 'Title has been Changed';  // Supported in macOScustomNotification.subtitle = 'Subtitle of the Notification';    customNotification.body = 'Body has been changed';  // Supported in macOScustomNotification.closeButtonText = 'Close Button'    // Supported in macOScustomNotification.hasReply = true;  // Supported in macOScustomNotification.replyPlaceholder = 'Reply Placeholder';   customNotification.silent = false;  // Supported in LinuxcustomNotification.urgency = 'low';  // Supported in Windows and Linux OS // This is a bug, as described above.customNotification.timeoutType= 'default';
Output: Upon adding these Instance properties to the index.js file, we should see the following. All non-compatible instance properties are ignored.My Personal Notes
arrow_drop_upSave
ElectronJS
Articles
HTML
JavaScript
Node.js
Web Technologies
HTML
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
Time Complexity and Space Complexity
Mutex vs Semaphore
Analysis of Algorithms | Set 3 (Asymptotic Notations)
Analysis of Algorithms | Set 2 (Worst, Average and Best Cases)
Understanding "extern" keyword in C
Top 10 Projects For Beginners To Practice HTML and CSS Skills
How to insert spaces/tabs in text using HTML/CSS?
How to set the default value for an HTML <select> element ?
How to update Node.js and NPM to next version ?
How to set input type date in dd-mm-yyyy format using HTML ?