Novu raised $6.6m seed funding

How to

Create a notifications system using in-app (bell icon) and emails

In this article, I will guide you through sending notifications in-app and via email using Novu in a Node.js application. We'll first create a Novu project, add an email communication channel via the Novu Manage Platform, install Novu to an Express app, and send in-app and email messages using Novu 🚀.

Nevo David
Nevo DavidJuly 25, 2022

Who is this article for?

You want to implement product notifications for your users, for example, in-app notifications (like the bell icon you have on Facebook), sending an email / SMS, or push notifications in a flow.

A quick example can be: Facebook sends you a notification into your bell icon (You have a new friend request), and after 1 hour you haven’t read it, they send you an email.

Why Novu?

Novu is the first open-source notification infrastructure that manages all forms of communication from email to SMS, Push notifications, etc.

It enables you to add several emails and SMS communication channels, create shared message templates, monitor every activity, and switch between different communication channels of your choice.

Central communication system

One of the reasons why Novu stands out is the ability to have a central means of communication. Novu provides a dashboard where you can monitor and manage all your SMS and email communications. With Novu, you can easily track communication via several channels on a single dashboard.

Several communication channels are available

With Novu, you can use as many communication channels as possible and easily switch from one to another without editing the existing code in your application.
For instance, if you use Sendgrid to send emails in your web application, but the service becomes unavailable for a moment, you can switch to other communication channels until Sendgrid is available without changing your code. Novu makes communication with your users easy to use and maintain.

Content management system

Novu provides every user with a content management system where you can create reusable email and SMS templates that you can share across various software applications. With Novu, you don’t need to worry about the stress of creating dynamic content. Novu uses handlebars templating engine to accept dynamic variables, thus, creating a unique experience for your users.

Open source software

Novu is open-source software; this means that the code is readily available for everyone to modify and improve. Novu has a large community of developers and talented contributors constantly maintaining and improving the software. As a user, you can be sure of getting the best performance when you use Novu. You can also request changes to the documentation, ask for help, and chat with the maintainers when you need help or encounter errors.

BTW: You can become a contributor and get recognized! We have created a special page for all our contributors with recognition for their super hard work, and badges they can implement on their Github 🚀
Grab a new issue here:

Ok, enough with the self-promotion 😆🔫, let’s start

Here, I will guide you through creating a Novu project and setting up Novu for sending emails and in-app notifications.

Create your project folder and open the folder.

1mkdir <folder_name>
2cd <folder_name>

Ensure you have Node.js installed on your computer, then run the code snippet below in your terminal to create a Novu project.

1npx novu init

You will need to sign in with Github before creating a Novu project. The code snippet below contains the steps you should follow after running npx novu init.

1Now let's setup your account and send your first notification
2❓ What is your application name? <Your_application_name>
3❓ Now lets setup your environment. How would you like to proceed? 
4   > Create a free cloud account (Recommended)
5   Create your account with: Sign-in with GitHub
6✔️ Create your account successfully.
8Now let's setup your account and send your first notification
9❓ Looks like you already have a created an account for Development (Use arrow keys)
10> Visit Development Dashboard
11  Cancel

The code snippet above opens the Novu Manage Platform in your default browser.

Novu Dashboard page

Novu Dashboard page

Congratulations 🎊, you’ve successfully created an account with Novu. Next, click the Configure Now button to add an Email provider. I will be using Sendgrid in this article.

How to add Sendgrid email provider to Novu

I have choosen Sendgrid but you can easily choose one of: Mailgun, SES, Postmark, NodeMailer, Mailjet, Mandrill, SendinBlue, and EmailJS.

If you are missing a provider, just open a new issue on Github 🙂

Let’s set up a new Sendgrid account and add it to Novu.

Open another tab, visit the Twilio Sendgrid website and create an account using a work or company email.

Sign in, click Settings on your sidebar, and select API Keys to create a SendGrid API key with full access to “Mail Send” permissions.

Copy the API key, and paste it into the Novu Manage Platform

Novu Sendgrid.png

Click the settings icon beside Twilio Sendgrid in the image above and paste the API Key into the API Key field.

Novu API field.png

Go back to your Sendgrid dashboard to create and verify a Sender Identity.

Paste the email address and the sender name into their fields in the image above, ensure it is active and click the Update button.

Congratulations 🎊, you have successfully connected your Sendgrid account to Novu, and you can start sending emails via Novu.

Next, let’s create a workflow showing how we want to send notifications in our Node.js application.

How to create a Novu notification workflow

Click Notifications from the sidebar and select the Notification template already created for you by default.

Select Workflow Editor to create the notification workflow, then drag the different notification channels from your right-hand side into the large box in the center of the page.

Novu workflow.png

Ensure the workflow is the same as the image above and click the Update button to save the steps.

Next, let’s create an Express app and add Novu to the Node.js application.

Adding Novu to an Express application

In this section, you’ll learn how to set up an Express Node.js server and add Novu to the application.

In the project’s folder created in the previous section, create a package.json file and an index.js file – the entry point to the Node.js application.

1cd <project-folder>
2npm init -y & touch index.js

Install Express and Novu SDK for Node.js. Express.js is a fast, minimalist framework that provides several features for building web applications in Node.js.

1npm install express @novu/node

Copy and paste the code snippet below into the index.js file to create an Express application.

1const express = require('express'); //import expressjs
2const app = express();
3const PORT = 4000; // where the server runs
4const path = require('path');
6//allows access to data sent from the client - index.html file
7app.use(express.urlencoded({ extended: true }));
9//creates a route that displays an index.html file.
10app.get('/', (req, res) => {
11  res.sendFile(path.join(__dirname, '/index.html'));
14//listens to updates made on the project and shows the status of the project
15app.listen(PORT, () => {
16  console.log(`⚡️[server]: Server is running at https://localhost:${PORT}`);

Create the index.html file referenced above and copy the code below into the file.

1<!DOCTYPE html>
3  <title>Generating Employment Letter</title>
4  <link rel="preconnect" href="">
5<link rel="preconnect" href="" crossorigin>
6<link href=";200;300;400;500;600;700;800;900&display=swap" rel="stylesheet">
7  <style>
8    * {
9      box-sizing: border-box;
10      margin: 0;
11      padding: 0;
12      font-family: 'Poppins', sans-serif;
13    }
14    form {
15      min-height: 100vh;
16      width: 100%;
17      padding: 30px;
18      display: flex;
19      align-items: center;
20      justify-content: center;
21      flex-direction: column;
22    }
23    input {
24      padding: 10px;
25      width: 100%;
26      outline: none;
27      border: 1px solid #ddd;
28      border-radius: 3px;
29      margin-bottom: 20px;
30    }
31    #button {
32      width: 200px;
33      padding: 20px;
34      outline: none;
35      border: none;
36      background-color: #333;
37      color: #fff;
38      cursor: pointer;
39      margin-top: 30px;
40      border-radius: 3px;
41    }
42    h2 {
43      margin-bottom: 20px;
44    }
45    .container {
46      display: flex;
47      width: 100%;
48      align-items: center;
49      justify-content: space-between;
50    }
51    .container div {
52      width: 45%;
53    }
54    #personnel {
55      margin-top: 30px;
56    }
57    #others div {
58      width: 30%;
59    }
61  </style>
64    <form method="POST" action="/sent">
65      <h2>Candidate's information</h2>
66      <div class="container">
67          <div>
68            <label for="candidateFirstName">Candidate's First Name</label>
69            <input type="text" name="candidateFirstName" id="candidateFirstName"/>
70          </div>
72          <div>
73            <label for="candidateLastName">Candidate's Last Name</label>
74            <input type="text" name="candidateLastName" id="candidateLastName"/>
75          </div>
76      </div>
78      <div class="container" id="others">
79          <div>
80            <label for="candidateEmail" >Candidate's Email</label>
81            <input type="email" name="candidateEmail" id="candidateEmail"/>
82          </div>
84          <div>
85            <label for="candidateSalary" >Proposed Salary</label>
86            <input type="number" name="candidateSalary" id="candidateSalary"/>
87          </div>
89          <div>
90            <label for="candidatePosition" >Proposed Position</label>
91            <input type="text" name="candidatePosition" id="candidatePosition"/>
92          </div>
93      </div>
95      <h2 id="personnel">Official Personnel</h2>
97        <div class="container">
98            <div>
99              <label for="officialFullName" >Full Name</label>
100              <input type="text" name="officialFullName" id="officialFullName"/>
101            </div>
102            <div>
103              <label for="officialPosition" >Position Held</label>
104              <input type="text" name="officialPosition" id="officialPosition"/>
105            </div>
106        </div>
108        <button id="button">SEND OFFER</button>
109    </form>

Run the index.js file by copying the code below. Visit http://localhost:4000 to view the index.html file.

1node index.js

Next, I will show you how to send emails and in-app notifications via Novu by creating a web application that generates offer letters for successful job applicants in an organization. The index.html file is the web client/layout of the application.

How to send email notifications using Novu

Here, I will guide you through creating email templates and sending them to users via Novu.

Go to the Novu Manage Platform, select the Notification template, and click on Workflow Editor.

Select Email from the large center box to edit the template.

Novu edit template.png

Novu allows us to add plain text and custom code using HTML templates with the Handlebars templating engine as email content.

Copy and paste this as the Subject line of the email


Select Custom Code as the content type and copy the code below. The email content and the subject line allow us to pass dynamic data into the variables using the Handlebars templating engine.

2  <p>Dear {{candidateFirstName}} {{candidateLastName}}</p>
3  <p>This is to inform you that you've been offered a position at Novu as a
4    {{candidatePosition}}
5    with a starting salary of
6    {{candidateSalary}}
7  </p>
8  <p>Kindly sign the attached document.</p>
9  <p>Congratulations, once again</p>
10  <br />
11  <p>{{officialFullName}} </p>
12  <p><em>{{officialPosition}}</em></p>

You can now save the template. Next, let me walk you through sending this template via email.

Import Novu into the index.js file. To get your API key, click on Settings on the Novu Manage Platform, select API Keys, and copy it into the code below.

1//Import and instantiate Novu in the index.js file
3const { Novu } = require('@novu/node');
4const novu = new Novu(<YOUR_API_KEY>);

Create a /sent route that accepts only POST requests in the index.js file, and copy the code below. This route receives all the user’s data from the client and logs them to the console.'/sent', (req, res) => {
2  //Gets the inputs from the web client
3  const {
4    officialPosition,
5    officialFullName,
6    candidateEmail,
7    candidateSalary,
8    candidatePosition,
9    candidateFirstName,
10    candidateLastName,
11  } = req.body;
13  //Logs the data to the client
14  console.log({
15    officialPosition,
16    officialFullName,
17    candidateEmail,
18    candidateSalary,
19    candidatePosition,
20    candidateFirstName,
21    candidateLastName,
22  });

Once you’ve retrieved the data from the client, update the POST route to send the email to the application using the Novu template.'/sent', async (req, res) => {
2  const {
3    officialPosition,
4    officialFullName,
5    candidateEmail,
6    candidateSalary,
7    candidatePosition,
8    candidateFirstName,
9    candidateLastName,
10  } = req.body;
12  await novu
13    .trigger('on-boarding-notification', {
14      to: {
15        subscriberId: '<YOUR SUBSCRIBER_ID>',
16        email: candidateEmail,
17      },
18      payload: {
19        officialPosition,
20        officialFullName,
21        candidateSalary,
22        candidatePosition,
23        candidateFirstName,
24        candidateLastName,
25      },
26    })
27    .then((data) => {
28      console.log(data);
29    })
30    .catch((err) => console.error(err));
32  // redirects to the sent.html file
33  res.sendFile(path.join(__dirname, '/sent.html'));

According to the code snippet above, I changed the callback function to an asynchronous one before adding Novu. Novu then triggers the email templates via its ID and sends the template to the candidate’s email. The payload object contains all the dynamic data required by the template.

To get your Subscriber ID, click on Settings on the Novu Manage Platform, and copy and paste the Application Identifier.

Create the sent.html file referenced in the code snippet above.

1<!DOCTYPE html>
2  <head>
3    <title>Email Sent!</title>
4  </head>
5  <body>
6    <p> Message sent!</p>
7  </body>

Start the Node.js server by running the code below.

1node index.js

To add attachments to the email messages, you can create an attachments array within the payload object or upload the document via the Novu Manage Platform.

1await novu
2    .trigger('on-boarding-notification', {
3      to: {
4        subscriberId: '<YOUR SUBSCRIBER_ID>',
5        email: candidateEmail,
6      },
7      payload: {
8        ...,
9        attachments: [
10          {
11            file: fs.readFileSync(__dirname + '/test.jpeg'),
12            name: 'test.jpeg',
13            mime: 'image/jpg',
14          },
15      ],
16      },
17    })
18    .then((data) => {
19      console.log(data);
20    }).catch((err) => console.error(err));

The code snippet above attaches an image to the email before sending the email to the recipient. Next, let’s learn how to send in-app notifications to the web client.

How to send in-app notifications using Novu

In this section, you’ll learn how to send in-app notifications and display them on the web client of your application.

Visit the Novu Manage Platform, select the template you are using, and click on Workflow Editor.

Select In-app from the large center box, click the Edit Template button to edit the notification and save the content.

Novu in-app notification.png

Update the sent.html file to contain the JavaScript code and the bell icon before its closing body tag. The JavaScript code displays the in-app notification bar when a user clicks the bell icon.

1<!DOCTYPE html>
3    <title>Sent!</title>
4    <!-- FontAwesome CDN link-->
5    <script src="" crossorigin="anonymous"></script>
9    <p> Message sent!</p>
11    <!-- The elements Novu needs to display the Notification bar -->
12    <div id="notification-bell" style="min-height: 300px; width: 100%">
13        <i class="fa fa-bell"></i>
14        <span id="unseen-badge"></span>
15    </div>
17    <script type="module">
18        (function(n,o,t,i,f, m) {
19          n[i] = {}, m = ['init']; n[i]._c = [];m.forEach(me => n[i][me] = function() {n[i]._c.push([me, arguments])});
20          var elt = o.createElement(f); elt.type = "text/javascript"; elt.async = true; elt.src = t;
21          var before = o.getElementsByTagName(f)[0]; before.parentNode.insertBefore(elt, before);
22        })(window, document, '', 'novu', 'script');
24        novu.init('Xr_knh-UYIPD', '#notification-bell', {
25          subscriberId: "Xr_knh-UYIPD",
26          email: "",
27          firstName: "Nevo",
28          lastName: "David",
29        });
30      </script>

NB: You can get the bell icon from Font Awesome and ensure the CSS id referenced in the JavaScript code exists in your HTML file.

Novu in-app notification bar.png

Source Code

You can check the complete source code here:
This is just the express server to interact with Novu.
Before you clone the project, please run.

1npx novu init


In this tutorial, you’ve learned what Novu is, why you should use it, how to create a Novu project, how to add Novu to an Express.js web application, and how to send emails and in-app notifications with Novu.

Novu makes it easy for you to send, monitor, and manage notifications via various SMS and Email communication channels. It enables you to create a rich notification system in your applications, thereby providing a great user experience for your users.

You can also join the community to contribute, chat with the maintainers and improve the software.

Thank you for reading!

Nevo David
Nevo DavidJuly 25, 2022

Related Posts

How to

Building a beautiful Kanban board with Node.js, React, and Websockets 🦄 ✨

In this article, you'll learn how to build a Kanban Board the same as you have in JIRA, Monday and Trello. We will do it with a beautiful drag-and-drop feature using React,, and React beautiful DND. Users will be able to sign in, create and update various tasks, and add comments.

Nevo David
Nevo DavidSeptember 28, 2022
How to

Building an interactive screen-sharing app with Puppeteer and React 🤯

Give the user the ability to browse a webpage through your system and feel like it's a real browser.

Nevo David
Nevo DavidSeptember 12, 2022
How to

Building a live-event alert system with React,, and Push Notifications 🚀

You want everybody to get a message on your website once something happens in real-time. That can be a new version, announcement, or some product updates.

Nevo David
Nevo DavidSeptember 5, 2022