I am attempting to use Nodemailer to send emails from a contact form on my site. I have a simple Express server sending the data via SMTP. My front-end is React and I have an onSubmit function that is taking care of the POST request as well as implementing a Google Recaptcha.
I am able to submit the form and successfully log the values in the input boxes. Nodemailer is successfully sending the email via SMTP and I am receiving the email. However, when the email is received all of the form data is undefined. The data from the form in my front-end is being logged to Nodejs and I can see the values, but in the email the values are undefined.
Here is my onSubmit handler that takes care of the POST requests:
function onSubmit(values) {
//ref for recaptcha
const token = reRef.current;
reRef.current.reset();
// Data from form that I am attempting to POST and send in the nodemailer email
const postData = {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
mode: "no-cors",
body: JSON.stringify({
name: values.name,
company: values.company,
phone: values.phone,
email: values.email,
heardAboutUs: values.heardAboutUs,
region: values.region,
message: values.howWeCanHelp
}),
};
// Handles form POST request
fetch('http://localhost:3000/send', postData)
.then(response => response.json())
.catch(err => console.log(err));
const captchaOptions = {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
mode: "no-cors"
}
const secret = 'nunyabidness';
const sitekey = 'nunyabidness';
//Handles recaptcha
fetch(`https://www.google.com/recaptcha/api/siteverify?secret=${secret}&response=${sitekey}`, captchaOptions)
.then(response => () => {
let data = response.json;
console.log(data)
})
.catch(err => console.log('Captcha error : ' + err))
}
Here is my Express server:
const express = require('express');
const bodyParser = require('body-parser');
const exphbs = require('express-handlebars');
const nodemailer = require('nodemailer');
const path = require('path');
const { response } = require('express');
const app = express();
// Public folder
app.use('/public', express.static(path.join(__dirname, 'public')));
// Body parser
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.get('/', (req, res) => {
res.render('contact', {layout: false});
});
app.post('/send', (req, res) => {
console.log(req.body);
const output = `
<h2>New Request a Demo Contact</h2>
// All these values are undefined in the email
<ul>
<li>Name: ${req.body.name}</li>
<li>Company: ${req.body.company}</li>
<li>Email: ${req.body.email}</li>
<li>Phone: ${req.body.phone}</li>
<li>Heard About Us: ${req.body.heardAboutUs}</li>
<li>Region: ${req.body.region}</li>
<li>How We Can Help: ${req.body.message}</li>
</ul>
`;
// create reusable transporter object using the default SMTP transport
let transporter = nodemailer.createTransport({
host: 'HOST_HERE',
port: 25,
secure: false,
ignoreTLS: true,
});
// setup email data with unicode symbols
let mailOptions = {
from: '"Website-Contact Form" <EMAIL_HERE>',
to: 'EMAIL_RECIPIENT_HERE',
subject: 'Node Contact Request',
html: output
};
// send mail with defined transport object
transporter.sendMail(mailOptions, (error, info) => {
if (error) {
res.status(500).send('error');
return console.log(error);
}
console.log('Message sent: %s', info.messageId);
console.log('Preview URL: %s', nodemailer.getTestMessageUrl(info));
res.status(200).send('success');
});
});
app.listen(3000, () => console.log('Server started'))
I removed the emails and keys for privacy.
Why are the form values successfully logging both in the client and node, but are undefined in the email?