4

I am creating an Email sending app using React and Node js. I am using Nodemailer for sending the emails. To get rich HTML and CSS in the email body, I am using React js to construct the email body. So, once the body is rendered by React js, it can be send through Nodemailer as html. Till now , I have been able to set the Nodemailer to work for simple text, attachments. I have constructed the Email body(with responsive HTML) in email.jsx. I have put a route('/send') to see how does it actually look on server side. I am facing problem so as to how can I compile this .jsx template that I have created and send this as html using Nodemailer. I know we can sure do this using Hogan if its a .hjs file. But how can I achieve the same for .jsx file. Please bear with me since I am new to React js.

Thisis email.jsx. I have used react js to construct the body of the email with materialize headers and footers. email.jsx

var React = require('react');
var Layout = require('./layout');

class Email extends React.Component {
render() {
    return (

        <Layout title={this.props.firstName}>
            <Layout text={this.props.textfield}>


                {/* Compiled and minified CSS */}
                <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.98.2/css/materialize.min.css" />
                {/* Compiled and minified JavaScript */}
                <div className="card-panel grey lighten-4">

                    <nav className="white">

                    <div className="nav-wrapper blue-grey darken-4">


                        <div className="brand-logo">
                            <div className="material-icons">Iowa State University<img src="https://s-media-cache-ak0.pinimg.com/736x/86/36/e4/8636e44169c2d51ef9d019c855f8537c.jpg" align="right" width={60} height={60} />

                        </div>

                            </div>

                        </div>
                    </nav>


                    {/*<div className="col s12 m2">*/}
                    {/*<p className="z-depth-4">z-depth-1</p>*/}
                    {/*</div>*/}
                    <div>
                        <style type="text/css" dangerouslySetInnerHTML={{__html: "\n  .header {\n    background: #8a8a8a;\n  }\n  .header .columns {\n    padding-bottom: 0;\n  }\n  .header p {\n    color: #fff;\n    padding-top: 15px;\n  }\n  .header .wrapper-inner {\n    padding: 20px;\n  }\n  .header .container {\n    background: transparent;\n  }\n  table.button.facebook table td {\n    background: #3B5998 !important;\n    border-color: #3B5998;\n  }\n  table.button.twitter table td {\n    background: #1daced !important;\n    border-color: #1daced;\n  }\n  table.button.google table td {\n    background: #DB4A39 !important;\n    border-color: #DB4A39;\n  }\n  .wrapper.secondary {\n    background: #f3f3f3;\n  }\n" }} />
                        <container>

                            <div className="card-panel grey lighten-5">
                            <spacer size={16} />
                            <row>
                                <columns small={6}>
                                    <h6>Hi, {this.props.firstName}</h6>
                                    <p className="lead">{this.props.firstParagraph}
                                    </p>
                                    {/*<p>{this.props.secondParagraph}*/}
                                    {/*</p>*/}
                                    {/*<callout className="primary">*/}
                                    {/*<p>{this.props.thirdParagraph} </p>*/}
                                    {/*</callout>*/}
                                </columns>
                            </row>
                            </div>
                            <wrapper className="secondary">
                            </wrapper>
                        </container>
                    </div>
                </div>
                    <footer className="page-footer blue-grey darken-4">
                        <div className="footer-copyright blue-grey darken-4">
                            <div className="container">
                                <div class="left-align">
                                © 2017 Copyright
                                </div>
                            </div>
                        </div>
                    </footer>
            </Layout>
        </Layout>
    );
}
}   
 Email.propTypes = {
title: React.PropTypes.string,
textfield: React.PropTypes.string,
firstParagraph: React.PropTypes.string,
// secondParagraph: React.PropTypes.string,
// thirdParagraph: React.PropTypes.string

};
module.exports = Email;

This is Mail.js. In this code, I am using nodemailer to send an email. mail.js

'use strict';
var express = require('express');
var router = express.Router();
var user = require('./users');
var path= require('path');
var nodemailer = require('nodemailer');
// var  React = require('react');

var fs= require('fs');
var Email= require('./email');
var ReactDOM= require('react-dom/server');
// var Template = require('../views/email.jsx');
var jsx = require('react-jsx')
, http = require('http')
, path = require('path')
// , React = require('react')
, read = require('fs').readFileSync;

var templates = {
email: jsx.server(read(path.join(__dirname, '/../views/email.jsx'), 'utf-8'))
};
var transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
    user: '',
    pass: ''
}
}, {
// default values for sendMail method
from: 'core9010@gmail.com',
headers: {
    'My-Awesome-Header': '123'
}
});

/* GET home page. */
exports.send=  function(req, res) {
transporter.sendMail({
    // to: 'dipitmalhotra@gmail.com',
    // cc: 'dipitmalhotra1@gmail.com',
    bcc: 'richardhendricks034@gmail.com',
    subject: 'hello',
    text: "It finally worked",
    html: How to get the the React rendered body here????
    ,
}, function (err, result) {
    if (err) {
        console.log('Error occurred');
        console.log(err.message);
        return;
    }
    console.log("Message sent successfully");
    console.log(result);

});
}

So, How can I get the React rendered body that that I created in email.jsx into "html" section of Nodemailer?

Man utd
  • 131
  • 2
  • 13
  • We're not going to be able to parse through your repo... please update with specific code examples and error messages. – BradByte Apr 22 '17 at 12:13
  • @BradBumbalough I have edited my questions and added the code. Please have a look at it.. I really need help on this – Man utd Apr 22 '17 at 15:16

1 Answers1

0

This is basically server side rendering but only you're sending it to the email client instead of the browser.

Have a look at ReactDOMServer.renderStaticMarkup. You would pass your the result of jsx.server into this and it will return the raw html you need to send to the email.

What needs to happen is that you have to convert the JSX template into raw React components... I've used babel in the past and I think that's where you were using react-jsx. That won't return HTML, just the converted components. You then need to pass that into ReactDOMServer.renderStaticMarkup to get the final HTML. Hope that helps!

BradByte
  • 11,015
  • 2
  • 37
  • 41
  • And what do you think will be the syntax for doing that.... var email_template= require('../views/layout.jsx') html: ReactDOMServer.renderStaticMarkup(email_template) ? – Man utd Apr 22 '17 at 16:35
  • Updated answer. Hope that helps! – BradByte Apr 22 '17 at 16:46
  • Thanks for the help..But I am still confused with the syntax..This is my first time with react and I am struggling a lot – Man utd Apr 22 '17 at 16:58