DEV Community

Cover image for Sending emails with Node.js
Andriy Zapisotskyi for Mailtrap

Posted on • Originally published at blog.mailtrap.io

Sending emails with Node.js

Sending emails from Node.js is easy. We have gone over it in our previous blog post on sending emails with Nodemailer. Last time we reviewed Nodemailer’s capabilities we focused on sending HTML emails via SMTP. In this post, we will examine how to send emails with Node.js using popular email servers like Gmail. Also, we will have a look at other transport options and packages to build and send emails from Node.js.  

The "Send emails in Node.js" blog post originally was published on Mailtrap's blog.

Building and sending emails with Node.js without Nodemailer

In some guides and tutorials, you might find a note that there are a variety of Node.js email packages but Nodemailer is the best one. It’s not true. In fact, you can barely find a decent alternative to Nodemailer (and I can hardly imagine why you might need it.)

On Github, you can find several Node.js packages related to emails but they won’t offer you a wide functionality. With Nodemailer, you can create HTML emails with attachments and send them via SMTP, SES (wrapper for sending emails via AWS SES), or sendmail

  1. The most similar package is Emaijs. Its features include: 
  • sending emails via SMTP servers (both SSL and TLS) with authentication
  • HTML support and MIME attachments (also, attachments can be added as strings, streams, or file paths)
  • asynchronous sending of queued emails 
  • UTF-8 encoding in headers and body.

So, the main difference is that in Emailjs you will use MIME type to work with attachments, while in Nodemailer you use strings. 

  1. Another quite popular package is email-templates. As you can see from the name, this package is designed for creating various custom templates for Node.js. It features support for automatic inline CSS, stylesheets, embedded images, and fonts. Also, it has an email preview option. The email templates package was made by the creator of the Lad framework. So it’s recommended to use it with Lad. 

  2. One more package worth mentioning here is Mailgen. It is aimed at creating HTML templates for transactional emails. There is a note on Github, that with Mailgen you can “Programmatically create beautiful e-mails using plain old JavaScript.” The package includes several open-source themes as well as supports custom elements like tables, action buttons, etc. It is your choice how to send an email created with Mailgen, but they recommend checking out Nodemailer for this purpose. 

| Feature | Nodemailer | Emailjs | Email templates | Mailgen |
| Building HTML emails | yes | Yes +MIME | Yes + CSS and customization | yes+CSS+themes |
| Email sending | SMTP, SES, sendmail | SMTP | Lad | no |
| Github rating (stars) (as on June 25, 2019) | 11,258 | 1,748 | 2,489 | 2,223 |
| Last commit (as on June 25, 2019) | May 26, 2019 | Sept 4, 2018 | June 23, 2019 | Jan 3, 2019 |

As you can see from the above table, Nodemailer is the most popular package, which offers functionality for both email creation and email sending. It’s not limited to one sending method. But it won’t be easy to create a special email template. This is why it might be a good idea to use Nodemailer in combination with another package.

To find all related packages and plugins, search for nodemailer in npm.

Sending HTML emails with dynamic content

In our previous blog post, we reviewed several examples of sending HTML emails with Nodemailer, embedding images, and attaching files. In most cases, for transactional emails like registration confirmation or resetting passwords, you need to use dynamic content. It will be easier and more efficient to do it with one of the template modules. 

Let’s experiment with the email-templates package. It has several interesting features:

  • Support for different template engines (Pug is a default one)
  • Email preview (by default) in the development environment
  • Direct email sending. So, you don’t need extra packages like Nodemailer for email sending. 

First of all, let’s create our templates, for a frequently occurring scenario: new user registration. In this example, we are working with the default option (for more details and samples of using Pug, refer to Github.) 

Install the template engine:

npm:

npm install email-templates pug
Enter fullscreen mode Exit fullscreen mode

yarn:

yarn add email-templates pug
Enter fullscreen mode Exit fullscreen mode

We should create two files: subject and HTML body.

subject.pug:

= `Hi ${firstName} ${lastName}, happy to see you at My App!`
Enter fullscreen mode Exit fullscreen mode

html.pug:

h1 Hello #{firstName} #{lastName}
    p.
Welcome to My App! Now your test emails will be safe. We just need to make sure your account is real. 
Please, click the button below and start using your account. 
a(href='https://example.com/confirmation') Confirm!
Enter fullscreen mode Exit fullscreen mode

Now make sure that your directory has the following structure:

├── app.js

├── emails

│   └── welcome (the template name)

│       ├── html.pug

│       ├── subject.pug

│       └── text.pug

Pay attention to the text part of your message: if you don’t include it, it will be generated automatically. But if you add it, it will be rendered automatically. This means that the content of the text and HTML parts may differ. 

Now we can write some code to gather all the elements together and add transport. As usual, we will use Mailtrap, to be able to test and check everything. In the same way, you can use any other SMTP server like Gmail, for example. Just be careful if experimenting with real email addresses!

const Email = require('email-templates');
const email = new Email({
 message: {
   from: 'hi@example.com'
 },
 send: true,
 transport: {
   host: 'smtp.mailtrap.io',
   port: 2525,
   ssl: false,
   tls: true,
   auth: {
     user: '1a2b3c4d5e6f7g', // your Mailtrap username
     pass: '1a2b3c4d5e6f7g' //your Mailtrap password
   }
 }
});

const people = [
 {firstName: 'Diana', lastName: 'One'},
 {firstName: 'Alex', lastName: 'Another'}
];

people.forEach((person) => {
 email
   .send({
     template: 'welcome',
     message: {
       to: 'test@example.com'
     },
     locals: person
   })
   .then(console.log)
   .catch(console.error);
}).
Enter fullscreen mode Exit fullscreen mode

By default, the preview of your email will be opened in your browser. It might be helpful if you are working on your template and don’t need to actually send the message. If you need to test how the variables work, and you compose a message to dozens or even hundreds of recipients, be careful with this option. To switch it off, specify options.open as false.

This is why we use Mailtrap: we will see how the message looks for each recipient, explore both HTML and text versions, and will be able to perform additional checks. With Pug and email-templates, you can build a complex template using CSS, inlined images, tables, etc. Here is an example of how it should look in the Mailtrap virtual inbox:

* HTML*

* Text*

Enjoyed the reading? Full guide in Node.js and Emails is available at Mailtrap blog.

Top comments (1)

Collapse
 
slidenerd profile image
slidenerd

decent post but like majority of the articles does not address the main pain points, how to queue emails for bulk sending, how to retry on failure and how to handle bounce