ReactJS is a fabulous library for building good-looking web applications. It can handle any kind of responsive interfaces and complex interactions you can think of. But things might get a bit tricky if you need to add some typically backend-minded functionalities to your web application. Think of a simple contact form placed at one of the subpages. While building a React email template will be a piece of cake (not that yummy, though!), adding sending capabilities requires a bit of research.
In this article, we’re covering various methods and we’ll also share some recommendations along the way.
Sending emails with ‘pure React’
Can you send even the simplest emails from a React-powered website without any 3rd-party plugins? Unfortunately not. React JS apps are run on the client-side (in a browser) and the SMTP server needs to be set up on the server-side. In theory, you could provide your SMTP credentials on the client-side, directly in the code. But since leaving such sensitive data for everyone to see and use is a rather poor idea, we’re not going to elaborate on it any further.
We’re going to talk later on about how to set up an express backend and add a 3rd party mailing capability. Let’s start with an easier method first, though!
Sending emails with EmailJS
Now, let’s look at the approach that won’t require setting up a backend at all.
We’ll set up an external tool to handle email sending for us and we’ll only make sure to trigger this tool when a mailing is due. We’re going to use a very popular service called EmailJS. It lets you connect your email client in the browser, build a template and send it with EmailJS API. The tool is not meant strictly for ReactJS and will also work perfectly with other frameworks such as Vue.js or Angular. There are lots of email services you can use it with, ranging from typical personal-email services such as Gmail and Outlook to more mass-email-bound tools like Mandrill or Mailgun. Pricings for each differ and most come with a free, limited tier.
For this example, we’ll stick with Gmail.
To get started, create an EmailJS account at https://www.emailjs.com and connect your desired email handling service.
Then, start building your first templates with the built-in email template editor. It’s really straightforward to use so we’re not going to go into details here. To make your emails more personalized, take advantage of dynamic variables. EmailJS also comes with other features, such as auto-reply or an option to add attachments. You can use `Email Template Example` which is added to your profile by EmailJS by default as a reference.
Now, it’s time to add EmailJS to your React project. If you are using a bundler like Webpack, install it with npm
as detailed here.
Alternatively, if your app was built with Create-React-App, you might add EmailJS directly to the head of public/index.html
file. For the following examples, we will provide explanations assuming you’re working with an app built with Create-React-App.
<script
src="https://cdn.jsdelivr.net/npm/emailjs-com@2.3.2/dist/email.min.js"></script>
<script>
(function () {
emailjs.init("<YOUR USER ID>"); // Obtain your user ID at the dashboard https://dashboard.emailjs.com/integration
})();
</script>
Once that’s set up, let’s move on to sending the actual email. EmailJS offers two methods for doing so:
- emailjs.send for basic email delivery
- emailjs.sendForm dedicated to webforms as it collected the data from its fields and passes them to the template of your choice
Here’s a sample code of a React email form component. Put it to the src/Form.js
file in your project.
import React from 'react';
export default class extends React.Component {
constructor(props) {
super(props);
this.state = { feedback: '', name: 'Name', email: 'email@example.com' };
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
render() {
return (
<form className="test-mailing">
<h1>Let's see if it works</h1>
<div>
<textarea
id="test-mailing"
name="test-mailing"
onChange={this.handleChange}
placeholder="Post some lorem ipsum here"
required
value={this.state.feedback}
style={{ width: '100%', height: '150px' }}
/>
</div>
<input type="button" value="Submit" className="btn btn--submit" onClick={this.handleSubmit} />
</form>
)
}
handleChange(event) {
this.setState({ feedback: event.target.value })
}
handleSubmit() {
// TODO
}
}
Now we need to add a handleSubmit()
function to our component to call sendFeedback()
function that will, as a result, trigger email sending via EmailJS. To keep it simple, we’ll use the default emailjs.send
function.
handleSubmit(event) {
const templateId = 'template_id';
this.sendFeedback(templateId, {message_html: this.state.feedback, from_name: this.state.name, reply_to: this.state.email})
}
sendFeedback (templateId, variables) {
window.emailjs.send(
'gmail',
templateId,
variables
).then(res => {
console.log('Email successfully sent!')
})
// Handle errors here however you like, or use a React error boundary
.catch(err => console.error('Oh well, you failed. Here some thoughts on the error that occured:', err))
}
Replace the function parameters with your own and test if everything went smoothly in the EmailJS dashboard.
Don’t forget to import and use your Form
component from the main component of your application which is located at src/App.js
.
That’s all! Went pretty smoothly, huh?
Setting up an Express backend and connecting 3rd parties
If EmailJS won’t work for your use case, there’s an option to set up your own backend quickly and connect the 3rd party tool for email sending. As mentioned in the beginning of this article, ReactJS itself doesn’t have sending capabilities.
The set up is very easy. This guide takes you step by step through the steps required to quickly build an Express Node.js backend.
Once you have the backend, it’s time to connect a service specializing in sending emails. This can be done using Mailtrap Email API, which will give you additional control over your email deliverability and help streamline the process of directing sending issues and quickly debugging them.
As you can see, the EmailJS approach is fairly quick to set up and will do its job for basic things, such as most contact forms. Since emails sent this way land usually in your inboxes, you don’t care much about formatting and styles. If the email workflow you just added is meant for the user’s inbox (for example, a newsletter confirmation form), you probably want to beautify the message a little bit. Let’s talk about how to do it.
Building an HTML template in ReactJS
As you know, ReactJS projects are built using reusable components, pieces of UI that can be grouped with one another and placed around web pages with almost no effort. To no surprise, building an email template in React works in exactly the same fashion.
If you’ve ever tried to build and deliver emails with any framework, you know how painful it can be. What looks great on your testing environment, might render as a completely random set of styles and copy on users’ devices. Many browsers recognize <style> tags but others will omit them. Others work with inline styles but, again – not all of them. As a result, even if you test your emails inside out, possibly something is bound to go wrong.
One tool that aims to prevent such troubles is Mjml. It’s a markup language that makes it easy to generate fully-responsive HTML templates. It comes with a large set of frequently used components that can be inserted in your mailings without coding them from scratch.
Another really useful tool you can use is React-html-email. It’s used to quickly build reusable components of your choice. You insert your code sample, however long it is, and immediately get a single-line code component you can use throughout the project. See the example below:
import React from 'react';
import { Email, Item, A } from 'react-html-email';
export default function InlineLink({ name, children }) {
return (
<Email title="link">
<Item>
Hello {name},
<A style={{ paddingLeft: 10 }} href="/blog/">Click me!</A>
</Item>
<Item>
{children}
</Item>
</Email>
)
};
Add the code from above to a file in your client project to src
directory and call it Email.js
. Don’t forget to add react-html-email
component to your project. Then import this component to client/src/Form.js
and renderEmail
from react-html-email
to client/src/Form.js
.
import MyEmail from './Email'
import { renderEmail } from 'react-html-email'
After that you can use the following line to generate HTML code of your message:
const messageHtml = renderEmail(<MyEmail name={this.state.name} />); // HTML code
React-html-email comes with an email validator that immediately checks and informs you if there were any errors in the component’s code.
There’s also a really interesting WYSIWYG email editor for React with drag & drop features, aptly known as React Email Editor. Check it out and see if it can accelerate your development.
Finally, whether you use these tools or not, there’s a bunch of tips to take into consideration when trying to build a responsive email template. This article makes for a fairly compelling source.
Sending emails with Nodemailer
Now, let’s assume we want to use Nodemailer to build a backend for our React email client. It’s perfectly doable and not so hard to set up.
Nodemailer is a go-to module for anyone needing to send emails with Node.js framework. If you followed the example above, you should have already both Create-React-App and Express server set up. If you don’t, do it before we start as we’ll be using both.
In this example, we’ll refer to a web form you could add to your website, for example, to let customers reach out quickly to your sales and support teams. Start off with building the UI of such form in ReactJS. Need some inspiration? Check out this list of 45 ready-to-implement React forms.
Now, add the code to handle the form submissions. There are tons of parameters that can be used with Nodemailer, review them here and add according to your needs. Here’s an example:
handleSubmit(event) {
const messageHtml = renderEmail(
<MyEmail name={this.state.name}>{this.state.feedback}</MyEmail>
);
axios({
method: 'POST',
url: 'http://localhost:3000/send',
data: {
name: this.state.name,
email: this.state.email,
messageHtml: messageHtml
}
}).then((response) => {
if (response.data.msg === 'success') {
alert('Email sent, awesome!');
this.resetForm()
} else if(response.data.msg === 'fail') {
alert('Oops, something went wrong. Try again')
}
})
}
Add axios
to your client application. In express_react_example/client
run:
npm install axios --save
And add the import to the express_react_example/client/Form.js
:
import axios from 'axios';
Make sure you reset the form once a message is submitted, in case a user wants to send another one.
resetForm() {
this.setState({ feedback: '' });
}
Now, it’s about time we add Nodemailer to our project (the backend part):
npm install nodemailer --save
and create a config file to store the credentials of an account we’re going to use. We’re adding it to the backend so there are no security concerns this time. Put this file next to your server source code and call it config.js
.
module.exports = {
USER: 'YOUR_EMAIL_ADDRESS',
PASS: 'PASSWORD_FOR_EMAIL'
}
Then, we’ll want to set up the transporter to deliver our messages. Nodemailer can be used with different types of transporters. We recommend the default one, referred to as SMTP transporter, due to the simplicity of installation and its reliability. If you’re not happy with it, you can also integrate other transporters with your Nodemailer campaign. We’ll stick with the default one here.
Route Nodemailer emails to the safe testing environment first.
First of all, we need to share our credentials with the SMTP transporter. Add the following code to your server source code which should be called server.js
if you followed the Express.js setup instructions:
const nodemailer = require('nodemailer');
const creds = require('./config');
var transport = {
host: 'your_host_here', // e.g. smtp.gmail.com
auth: {
user: creds.USER,
pass: creds.PASS
}
}
var transporter = nodemailer.createTransport(transport)
transporter.verify((error, success) => {
if (error) {
console.log(error);
} else {
console.log('All works fine, congratz!');
}
});
Once done, we set up the post route to take our emails to its final destination – our inbox!
app.use(express.json());
app.post('/send', (req, res, next) => {
const name = req.body.name
const email = req.body.email
const message = req.body.messageHtml
var mail = {
from: name,
to: 'RECEIVING_EMAIL_ADDRESS_GOES_HERE',
subject: 'Contact form request',
html: message
}
transporter.sendMail(mail, (err, data) => {
if (err) {
res.json({
msg: 'fail'
})
} else {
res.json({
msg: 'success'
})
}
})
})
Now run the backend by running the following command in the root of your application:
node server.js
And run the frontend part too by running the command at the client
directory:
npm start
All done! You should receive an email, the form will reset and a user should see the confirmation you added in your React project.
Summary
We’ve tried to summarize various methods that can be used to send emails in ReactJS. Given how powerful and useful React is for nearly all kinds of projects, you don’t want to get stuck on something as simple as form submission. By all means, try them all and see which fits best for your project. Best of luck!