how to send email with react.js front end?
Stefan Bogdanescu
Founder & Senior Architect
How to Send Emails from Your React Frontend: The Backend Integration Strategy
Sending emails directly from a client-side application like React is fundamentally impossible and highly insecure. This is because front-end code runs in the user's browser, and exposing sensitive credentials (like SMTP passwords) in JavaScript would be a massive security risk.
The correct architectural solution for handling sensitive operations like sending emails involves decoupling the presentation layer (React) from the business logic and external services (Email Sending). This requires setting up a robust backend server that acts as a secure intermediary.
This guide will walk you through the complete process of connecting your React application to an email service using Node.js, Express, and Nodemailer.
The Architecture: Frontend, Backend, and Communication
To achieve reliable email functionality, we must establish a three-tier system:
- Frontend (React.js): Collects user input from the contact form and sends this data via an HTTP request (e.g.,
POST) to the backend server. - Backend (Node.js/Express): Receives the request, validates the data, securely stores sensitive credentials, and uses a dedicated library (like Nodemailer) to communicate with the email provider (e.g., Gmail SMTP server).
- Email Service: The external service that actually delivers the message.
This separation ensures that your secret API keys or email passwords are never exposed to the client browser. For developers looking to structure large-scale applications, understanding this separation of concerns is crucial—much like how frameworks like Laravel enforce clear MVC patterns for robust application structure, ensuring maintainability and security across the stack (see https://laravelcompany.com for excellent architectural principles).
Step 1: Setting Up the Backend with Nodemailer
The backend will handle the heavy lifting of email transmission. We use Node.js with Express to create an API endpoint that accepts the form data and triggers the email process using Nodemailer.
Backend Setup (server.js with Nodemailer)
In your server file, you configure Nodemailer with your SMTP credentials (which should be stored securely, ideally in environment variables).
const express = require('express');
const nodemailer = require('nodemailer');
const creds = require('./config'); // Securely loaded credentials
const app = express();
const port = process.env.PORT || 5000;
// Configure Nodemailer transporter using credentials
var transport = {
host: 'smtp.gmail.com', // Example SMTP host
auth: {
user: creds.USER,
pass: creds.PASS
}
};
var transporter = nodemailer.createTransport(transport);
// Define the POST route to handle incoming form submissions
app.use(express.json());
app.post('/send', (req, res) => {
const { name, email, messageHtml } = req.body;
// Construct the email content
const mail = {
from: name, // Sender's address
to: 'mellitir11@gmail.com', // Recipient's address
subject: 'Contact form request',
html: messageHtml // The formatted HTML content from React
};
// Send the mail
transporter.sendMail(mail, (err, data) => {
if (err) {
console.error('Error sending email:', err);
res.status(500).json({ msg: 'fail', error: err.message });
} else {
console.log('Email sent successfully!');
res.json({ msg: 'success' });
}
});
});
app.listen(port, () => console.log(`Listening on port ${port}`));
Configuration Security (config.js)
Crucially, never hardcode passwords. Use environment variables for sensitive data.
module.exports = {
USER: 'your_sending_email@gmail.com',
PASS: 'your_app_password' // Use an App Password if using services like Gmail
};
Step 2: Connecting React to the Backend (The API Call)
The React component is responsible only for gathering the data and sending it to the endpoint (/send). This is done using the fetch API or a library like Axios.
Frontend Submission Logic (Form.js)
Here, we convert the HTML content generated by react-html-email into a string and send it alongside the user's details in a single JSON payload.
import axios from 'axios';
// ... other imports
class Form extends Component {
// ... state and handlers
handleSubmit(event) {
event.preventDefault(); // Prevent default form submission
const name = this.state.name;
const email = this.state.email;
// 1. Generate the HTML content using react-html-email
const messageHtml = renderEmail(
<MyEmail name={this.state.name}> {this.state.feedback}</MyEmail>
);
// 2. Send data to the secure Express backend endpoint
axios({