Send Emails in node js using nodemailer, grandjs, and JSX components
Tags: node, grandjs, backend, nodemailer
Published: 2020-07-09 19:10:18

---
title: Send Emails in node js using nodemailer, grandjs, and JSX components
published: true
description: In this article, you will learn how to send emails with templates in node js using nodemailer and grandjs for templating your mails
tags: nodejs, grandjs, backend, nodemailer
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/9fnj186klt7e2sjsg4ke.png
---

Building server-side applications became easier after the revolution of single-page apps which clear the hassle from your backend code and your backend is no longer render views, and the UI is being rendered from the frontend, which gives your backend the freedom from using template engine and let your backend to focus on your REST APIs only.

This sounds good for most cases but about if you have a blog or eCommerce website and want to send emails to your users contains the latest news, products or even send to them a reminder for something, here the need to a template engine which you need to integrate it with nodemailer to render data inside it and then send this template to your users.
In this case, the first thing you will think about which template engine you can you use to accomplish this task without being a pain in rendering the data inside your template and do all of this frontend stuff, however you may be in the right way but you should be noted that the age of template engines in the backend has gone, and now is the age of JSX!

## What is JSX
Simply JSX is a syntax that enables you to write HTML elements inside the javascript file without any need to use normal static HTML files or even use a template engine to render dynamic data inside HTML elements. It was introduced for the first time by reactjs to render HTML elements from javascript for your frontend application to build a single-page app.

Now JSX is not only used in frontend development but it also can be used inside your backend application. One of these frameworks that use JSX inside the backend is [Grandjs](https://grandjs.netlify.app/) which is a full backend framework that enables you to write JSX components to do server-side rendering or to use these components to render as mail templates!

## About Grandjs
Grandjs is a full backend framework that enables you to build solid server-side applications based on nodejs, js, and typescript, and one of these powerful features is using JSX components to render HTML elements either for SSR or for sending email templates to your clients!
You can find the full documentation from [here](https://grandjs.netlify.app/)

## What we will do?
In this article, I will just show you how to render an email template using nodemailer, JSX, and grandjs.

**Note**
You can use grandjs with any other server framework you use if you want to use it just for sending email templates

### Install Dependencies
Just run the following command to install the following dependencies:
- nodemailer
- grandjs

```CMD
npm i --save nodemailer grandjs dotenv
```

Then your project structure can be as the following

- index.js
- views
- Mailer.js
- data.json
- .env

In `index.js` you just need to import `View` class from grandjs to set  its configurations as the following:

```javascript
const {View} = require("grandjs")

// set configuration for views

View.settings.set("views", "./views")
```

Then create a new component in `views` directory, this component will be called `Newsletter.jsx`

**Note**
the name of the component should be with `.jsx` extension
In each component you define in a file you should import `View` class as the following:

```javascript
const {View} = require("grandjs");
```
After that we will define our styles as js object as we do in reactjs

```javascript
const Styles = {
    body: {
        backgroundColor:"#ccc",
        margin:"0px",
        padding:"0px"
    },
    section_one: {
        padding:"30px",
        margin:0
    },
    container: {
        maxWidth: "600px",
        margin:"0 auto",
        backgroundColor:"white",
        fontSize:"0px",
        padding:"0px",
        fontFamily:"'Roboto',sans-serif",

    },
    header: {
        textAlign:"center",
        height:"50px",
        padding:"0px",
        margin:"0px",

    },
    headerline: {
        backgroundColor:"#E6FFF7",
        textAlign:"center",
        fontSize:"20px",
        color: "#333",
        lineHeight: "40px",
        fontWeight:"400px",
        margin:"0px",
    },
    img: {
        display:"inline",
        width:"25%",
        verticalAlign:"middle",
    },
    paragraph: {
        display:"inline-block",
        fontSize:"14px",
        fontWeight:"300",
        color:"#666",
        width:"calc(75% - 40px)",
        padding:"0 20px",
        margin:"0",
        lineHeight:1.4,
        verticalAlign:"middle",

    },
    btn: {
        display:"block",
        backgroundColor:"#29F0C2",
        fontSize:"18px",
        color:"white",
        padding:0,
        margin:"30px auto 0",
        border:0,
        borderRadius:"5px",
        lineHeight:"40px",
        height:"40px",
        width: "200px",
        textAlign:"center"
    }

}
```

Then you can define your jsx component as a functional component as the following:

```jsx
const {View} = require("grandjs");

const NewsLetter = () => {
     <div>
      <body style={Styles.body}>
        <div
        style={Styles.container}
        >
          <div
          style={Styles.header}
          >
            <h1>Your daily News is here!</h1>
          </div>
          {data.news.map((item) => {
              return (
                <div>
                <h2
                style={Styles.headerline}
                >
                  {item.title}
                </h2>
                <div class="section_one" style={Styles.section_one}>
                  <img
                    src={item.img}
                    style={Styles.img}
                  />
                  <div
                    class="paragraph"
                    style={Styles.paragraph}
                  >
                    {item.description}
                  </div>
                  <a
                    href={item.link}
                    class="btn"
                    style={Styles.btn}
                  >
                    Read Article
                  </a>
                </div>
              </div>
            
              )
          })}          
          </div>
      </body>
    </div>

}
```

So the final file would be as the following:

```jsx
const { View } = require("grandjs");


const Styles = {
    body: {
        backgroundColor:"#ccc",
        margin:"0px",
        padding:"0px"
    },
    section_one: {
        padding:"30px",
        margin:0
    },
    container: {
        maxWidth: "600px",
        margin:"0 auto",
        backgroundColor:"white",
        fontSize:"0px",
        padding:"0px",
        fontFamily:"'Roboto',sans-serif",

    },
    header: {
        textAlign:"center",
        height:"50px",
        padding:"0px",
        margin:"0px",

    },
    headerline: {
        backgroundColor:"#E6FFF7",
        textAlign:"center",
        fontSize:"20px",
        color: "#333",
        lineHeight: "40px",
        fontWeight:"400px",
        margin:"0px",
    },
    img: {
        display:"inline",
        width:"25%",
        verticalAlign:"middle",
    },
    paragraph: {
        display:"inline-block",
        fontSize:"14px",
        fontWeight:"300",
        color:"#666",
        width:"calc(75% - 40px)",
        padding:"0 20px",
        margin:"0",
        lineHeight:1.4,
        verticalAlign:"middle",

    },
    btn: {
        display:"block",
        backgroundColor:"#29F0C2",
        fontSize:"18px",
        color:"white",
        padding:0,
        margin:"30px auto 0",
        border:0,
        borderRadius:"5px",
        lineHeight:"40px",
        height:"40px",
        width: "200px",
        textAlign:"center"
    }

}
const Newsletter = ({data}) => {
  return (
    <div>
      <body style={Styles.body}>
        <div
        style={Styles.container}
        >
          <div
          style={Styles.header}
          >
            <h1>Your daily News is here!</h1>
          </div>
          {data.news.map((item) => {
              return (
                <div>
                <h2
                style={Styles.headerline}
                >
                  {item.title}
                </h2>
                <div class="section_one" style={Styles.section_one}>
                  <img
                    src={item.img}
                    style={Styles.img}
                  />
                  <div
                    class="paragraph"
                    style={Styles.paragraph}
                  >
                    {item.description}
                  </div>
                  <a
                    href={item.link}
                    class="btn"
                    style={Styles.btn}
                  >
                    Read Article
                  </a>
                </div>
              </div>
            
              )
          })}          
          </div>
      </body>
    </div>

    );
};

module.exports = Newsletter;
```
After that, I will create a file called `data.json`, this file will includes the mails that we want to send to and the news that we want to send as the following:



```json
{
    "users": ["user@email.com"],
    "news": [
        {
            "title": "React Infinite Scroll Tutorial: With and Without a Library",
            "img": "https://res.cloudinary.com/practicaldev/image/fetch/s--a8DByl-W--/c_imagga_scale,f_auto,fl_progressive,h_420,q_auto,w_1000/https://res.cloudinary.com/practicaldev/image/fetch/s--1QH-jSvc--/c_imagga_scale%2Cf_auto%2Cfl_progressive%2Ch_420%2Cq_auto%2Cw_1000/https://dev-to-uploads.s3.amazonaws.com/i/ttz2sso79x6cl7chdjml.jpg",
            "description": "Infinite scroll is a modern web & application design concept that loads content continuously as the user scrolling down the page. It changes the function of pagination.",
            "link": "https://dev.to/syakirurahman/react-infinite-scroll-tutorial-with-and-without-a-library-1abg"
        },
        {
            "title": "React App with Tailwind CSS / Emotion / Twin Macro",
            "img": "https://res.cloudinary.com/practicaldev/image/fetch/s--lmHWjUIc--/c_imagga_scale,f_auto,fl_progressive,h_420,q_auto,w_1000/https://res.cloudinary.com/practicaldev/image/fetch/s--atZRMw7r--/c_imagga_scale%2Cf_auto%2Cfl_progressive%2Ch_420%2Cq_auto%2Cw_1000/https://dev-to-uploads.s3.amazonaws.com/i/zbydh2m62o81na2n5fq8.png",
            "description": "I'll explain how install and configure Tailwind CSS / Emotion and twin.macro in a Single Project of React to improve the way we use styles in our projects.",
            "link": "https://dev.to/angelcodes/react-app-with-tailwind-css-emotion-twin-macro-3dpe"
        },
        {
            "title": "Currying in JavaScript",
            "img": "https://res.cloudinary.com/practicaldev/image/fetch/s--UvT9Kb3S--/c_imagga_scale,f_auto,fl_progressive,h_420,q_auto,w_1000/https://res.cloudinary.com/practicaldev/image/fetch/s--vw8755uu--/c_imagga_scale%2Cf_auto%2Cfl_progressive%2Ch_420%2Cq_auto%2Cw_1000/https://dev-to-uploads.s3.amazonaws.com/i/viplwlivvz3xxahdycac.png",
            "description": "Currying is a process in functional programming in which we can transform a function with multiple arguments into a sequence of nesting functions. It returns a new function that expects the next argument inline.",
            "link": "https://dev.to/suprabhasupi/currying-in-javascript-1k3l"
        }
    ]
}
```
Then we will create `Mailer.js` which will be a class responsible for sending emails
Firstly we will import `View` class from grandjs, `View` has a built-in method called `importJsx` that enables you to import JSX component into javascript file as the following:

```javascript
const { View } = require("grandjs");
const NewsLetter = View.importJsx("./views/Newsletter.jsx");
```
Then we will require `data.json` file that contains our data:

```javascript
const data = require("./data.json");

```
We will use Google account to send the emails and the mailer configuration will be something like the following:

```javasdcript
class Mailer{

    constructor() {
        this.config = {
            secure: true,
            service: "Gmail",
            host: "smtp.gmail.com",
            port: 465,
            auth: {
                user: process.env.MailUsername,
                pass: process.env.MailPassword
            }
        }
    }
}
```
As you can see, we read user and pass from process.env because we will pass these secret data as environment variables in the .env file and load this file using dotenv package

Then we will create a method inside `Mailer` class, this method will be called `sendNewsLetter` as the following:

```javascript
async sendNewsLetter() {
        try {
            console.log(data.users, this.config)
            const transporter = NodeMailer.createTransport(this.config);
            let template = View.renderToHtml(NewsLetter, {data})
            const mailOptions = {
                from: this.config.auth.user,
                to: data.users,
                subject: "Daily News",
                html: template,
            };
            await transporter.sendMail(mailOptions);
            console.log("mail sent successfully");
        } catch(err) {
            console.log(err);
        }
    }
```
As you can see above we use another function inside `View`, this function called `renderToHtml` which enables you to convert the written JSX component into normal HTML elements as a string, then you will be able to send this HTML string as mail template.

Then we specified the mail options such as `from` which means from which email that this mail is sent, `to`, which represents the targeted emails and this can be a string or an array, and the subject and finally the HTML template
The final Mailer file can as the following:

```javascript
const { View } = require("grandjs");
const NodeMailer = require("nodemailer");
const data = require("./data.json");
const NewsLetter = View.importJsx("./views/Newsletter.jsx");

class Mailer{

    constructor() {
        this.config = {
            secure: true,
            service: "Gmail",
            host: "smtp.gmail.com",
            port: 465,
            auth: {
                user: process.env.MailUsername,
                pass: process.env.MailPassword
            }
        }
    }
    async sendNewsLetter() {
        try {
            console.log(data.users, this.config)
            const transporter = NodeMailer.createTransport(this.config);
            let template = View.renderToHtml(NewsLetter, {data})
            const mailOptions = {
                from: this.config.auth.user,
                to: data.users,
                subject: "Daily News",
                html: template,
            };
            await transporter.sendMail(mailOptions);
            console.log("mail sent successfully");
        } catch(err) {
            console.log(err);
        }
    }
}


module.exports = new Mailer();
```
Then in `index.js` we will update it to load our `.env` file as the following:

```javascript
require("dotenv").config();
const {View} = require("grandjs")

View.settings.set("views", "./views");
```
Then import the `Mailer.js` file as the following:
```javascript
const Mailer = require("./Mailer");
```
Then just call `sendNewsLetter` function to send the mail

```javascript
require("dotenv").config();
const {View} = require("grandjs")

View.settings.set("views", "./views");

const Mailer = require("./Mailer");

Mailer.sendNewsLetter();
```

Now you just need to create `.env` file and define the following variables inside it:
```
MailUsername=your_sender_email
MailPassword=your_sender_email_password

```

Now you can run your application by giving the following command:
```CMD
node index
```
the mail template is sent now!

![Mail Temaplate](https://dev-to-uploads.s3.amazonaws.com/i/xxdng7tk2v0e2qmny9jm.png)