The Nodemailer package in a Node.js Server

Emails are an essential way of communicating. Most servers today use emails to send information to clients. In this tutorial, we are going to create a server that does the same. We will be sending two types of emails; plain text and HTML emails.

You can get the starter code from Github. It has the following packages.

  1. Express – we will be creating a node server with the help of express.js
  2. Nodemailer – this npm package sends emails using SMTP as it’s primary transport. It is also used to create plugins like nodemailer-postmark-transportgmail-nodemailer-transport, etc.
  3. Pug – it is a templating engine used to create HTML strings to be rendered.

Before we start, it’s important to note that we won’t be sending emails to real addresses. This can result in a lot of unnecessary emails in the inbox and/or spam messages. To avoid this, we can use a fake SMTP server that can receive our test emails.

A good service to do this with is Ethereal. It will provide us with the required SMTP configurations and the nodemailer configuration. Go ahead and create an account. Copy the Nodemailer configuration and add it to the app.js file. It should look something like the code below:

const transporter = nodemailer.createTransport({
    host: 'smtp.ethereal.email',
    port: 587,
    auth: {
        user: '<some-username>',
        pass: '<some-password>'
    }
});

Then import the nodemailer and express package and initialize the app.

const express = require('express')
const app = express()
const nodemailer = require('nodemailer')
const transporter = nodemailer.createTransport({
    host: 'smtp.ethereal.email',
    port: 587,
    auth: {
        user: '<some-username>',
        pass: '<some-password>'
    }
});

app.use(express.json());
app.listen('2400', () => {console.log('server started on port 2400')})
module.exports = app;

The first email we will send will be a plain text email. We use the sendEmail function of Nodemailer transport to send the emails. It takes in the email data as one of the parameters. The data includes:

  • from – the senders email address
  • to – the recipient email address
  • subject – the subject of the email
  • text/html – the content of the email. It can be plain text or html.

Go ahead and create an endpoint that sends a plain text email.

app.get('/email/text', (req, res) => {
    transporter.sendMail({
        from: '"moose" <me@moose.dev>',
        to: '"You there" <you@there.com>',
        subject: 'First email',
        text: 'Hello, nice to meet you'
    })
        .then(info => res.send(info))
        .catch(error => res.send(error))
})

As you can see, it returns a promise and we return the response or error from the sendEmail function. If it was successful, you will get the email in the Ethereal inbox. It is as simple as that.

For HTML, we add the tags inside a string and it will detect the content and style and display it .

app.get('/email/html', (req, res) => {
    transporter.sendMail({
        from: '"moose" <me@moose.dev>',
        to: '"You there" <you@there.com>',
        subject: 'Second email',
        html: '<h1>Hi again</h1> <p>This time we have used html!</p>'
    })
        .then(info => res.send(info))
        .catch(error => res.send(error))
})

In this endpoint we get an email with a header and a paragraph below it. A very small difference with the plain text. The only problem with this is that we may need to load a whole webpage in the string. This results in dirty and unreadable code.

To solve that, we can make use of a templating engine. We can use it to generate the entire HTML code then we can pass it in the HTML value. For that, we will use Pug.

First, create a package in the root-level of the project and name it views. Inside the package, create a file, and name it email.pug and add the following code.

html
    head
        title Pug Email template
    body
        h1 Hey there
        p We have now used a pug file. Yaay!

You will notice that we do not use the angle-brackets with pug and indentation is also very important. It shows relationship between elements. Read more about it in the official documentation. Go ahead and import the package then add the following endpoint.

app.get('/email/file', (req, res) => {
    let body = pug.renderFile('views/email.pug')
    transporter.sendMail({
        from: '"moose" <me@moose.dev>',
        to: '"You there" <you@there.com>',
        subject: 'Third email',
        html: body
    })
        .then(info => res.send(info))
        .catch(error => res.send(error))
})

As you can see, we use the renderFile function to compile our Pug code to HTML and get the resulting string. Then we pass the string to the HTML field. The good thing about this is that you can have a wide variety of elements and still have clean and organized code.

With that, you are now able to send emails from your Node.js server. You can use the Gmail SMTP settings to send emails to real addresses. A good challenge can be adding images to your email so go ahead and try it out! The full code of this tutorial can be found on Github. Feel free to open a PR or submit an issue.

Related posts:

Building A Real-Time Retrospective Board With Video Chat
Debugging a Node.js app running in Docker using Nodemon and the Docker extension
Getting Started with HTTP/2 in Node.js
Build and Dockerize a Full-stack React app with Node.js, MySQL and Nginx
Choosing Between NPM and Yarn
Node.js vs Django
Next Generation Server Compression With Brotli
Useful Node.js Tools, Tutorials And Resources
How To Develop A Chat Bot With Node.js
Creating a Weather app in Node.js using the Openweathermap API
How to use Streams in Node.js
APIs in Node.js vs Python - A Comparison
Agora Cloud Recording with Node.js
Getting Started with Google Drive Node.js API
Creating A Continuous Integration Test Workflow Using GitHub Actions
Documenting a Node.js REST API using Swagger
How to Build an Authentication API with JWT Token in Node.js
How to Use Modular Patterns in Node.js
Getting Started with Node.js Paypal Checkout Integration
Building a Simple Cryptocurrency Blockchain using Node.js
How to Build a Static site with Gatsby.js
Making cURL Requests in Node.js
Keeping Node.js Fast: Tools, Techniques, And Tips For Making High-Performance Node.js Servers
How To Auto-generate Admin Panels for Node.js with AdminBro
How to Create a Simple REST API using TypeScript and Node.js
Making a Discord Bot (With Node.js)
React Server Side Rendering With Node And Express
How To Build A Skin For Your Web App With React And WordPress
Node.js versus Next.js - A React Approach
Web Scraping With Node.js
Getting Started with billboard.js charts
Introduction to the Koa.js Framework