Why do emails from my contact form bounce?

  • Thread starter Thread starter Darkmisc
  • Start date Start date
Click For Summary
SUMMARY

The forum discussion centers on troubleshooting email delivery issues from a React contact form using Nodemailer. The user experiences bounced emails when attempting to send messages to their Gmail account, receiving an error indicating that the domain "example.com" cannot be found. Key recommendations include correcting the "from" field in the email configuration to use the user's input email address and ensuring proper authentication credentials are used from a separate config file. Additionally, debugging techniques such as enabling logging in Nodemailer are suggested to diagnose the issue further.

PREREQUISITES
  • Familiarity with React.js for building the contact form
  • Understanding of Nodemailer for sending emails in Node.js applications
  • Basic knowledge of Express.js for handling server requests
  • Experience with Axios for making HTTP requests
NEXT STEPS
  • Learn how to configure Nodemailer with proper authentication and email headers
  • Explore debugging techniques in Node.js applications, particularly using console logging
  • Research best practices for handling form submissions in React
  • Investigate CORS settings and their implications in web applications
USEFUL FOR

Web developers, particularly those working with React and Node.js, as well as anyone implementing email functionality in web applications.

Darkmisc
Messages
222
Reaction score
31
TL;DR
When I click submit on my contact form, I get emails at the right address, but it's saying "Your message wasn't delivered to your-email@example.com because the domain example.com couldn't be found. Check for typos or unnecessary spaces and try again."
I have not specified your-email@example.com as my recipient address anywhere in my code.
Hi everyone

I'm making an email contact form that's supposed to send emails to my-email@gmail.com.

When I click submit, I'll get an email at my-email@gmail.com saying:
Your message wasn't delivered to your-email@example.com because the domain example.com couldn't be found. Check for typos or unnecessary spaces and try again.

That is, the email from the submission form is bouncing and it seems to think your-email@example.com was the intended address.
However, I can't find your-email@example.com anywhere in my code (I can't even find it where I originally got the code https://mailtrap.io/blog/react-contact-form/).

Does anyone know why it's doing this?


Thanks


[CODE lang="javascript" title="email.js"]import React from 'react';
import axios from 'axios';

class Email extends React.Component {
constructor(props) {
super(props);
this.state = {
name: '',
email: '',
telephone: '',
message: ''
};
}

handleSubmit(e) {
e.preventDefault();
axios({
method: "POST",
url: "http://localhost:3003/send",
data: {
name: this.state.name,
email: this.state.email,
telephone: this.state.telephone,
message: this.state.message
}
}).then((response) => {
if (response.data.status === 'success') {
alert("Message Sent.");
this.resetForm();
} else if (response.data.status === 'fail') {
alert("Message failed to send.");
}
});
}

resetForm() {
this.setState({ name: '', email: '', telephone: '', message: '' });
}

onNameChange(event) {
this.setState({ name: event.target.value });
}

onEmailChange(event) {
this.setState({ email: event.target.value });
}

onTelephoneChange(event) {
this.setState({ telephone: event.target.value });
}

onMessageChange(event) {
this.setState({ message: event.target.value });
}

render() {
return (
<div>
<form id="contact-form" onSubmit={this.handleSubmit.bind(this)} method="POST">
<div>
<label htmlFor="name">Name</label>
<input type="text" id="name" value={this.state.name} onChange={this.onNameChange.bind(this)} />
</div>
<div>
<label htmlFor="email">Email address</label>
<input type="email" id="email" value={this.state.email} onChange={this.onEmailChange.bind(this)} />
</div>
<div>
<label htmlFor="telephone">Telephone number</label>
<input type="tel" id="telephone" value={this.state.telephone} onChange={this.onTelephoneChange.bind(this)} />
</div>
<div>
<label htmlFor="message">Message</label>
<textarea rows="5" id="message" value={this.state.message} onChange={this.onMessageChange.bind(this)} />
</div>
<button type="submit">Submit</button>
</form>
</div>
);
}
}

export default Email;[/CODE]


[CODE lang="javascript" title="index.js" highlight="12, 43"]var express = require('express');
var router = express.Router();
var nodemailer = require('nodemailer');
var cors = require('cors');
const creds = require('./config');

var transport = {
host: 'smtp.gmail.com',
port: 465,
secure: true,
auth: {
user: 'my-email@gmail.com',
pass: 'aaaa bbbb cccc dddd'
}
};

var transporter = nodemailer.createTransport(transport);
transporter.verify((error, success) => {
if (error) {
console.log(error);
} else {
console.log('Server is ready to take messages');
}
});

const app = express();

// Enable CORS
app.use(cors());

app.use(express.json());
app.use('/', router);

router.post('/send', (req, res, next) => {
var name = req.body.name;
var email = req.body.email;
var telephone = req.body.telephone;
var message = req.body.message;
var content = `Name: ${name}\nEmail: ${email}\nTelephone: ${telephone}\nMessage: ${message}`; // Include telephone in the content

var mail = {
from: name,
to: 'my-email@gmail.com',
subject: 'New Message from Contact Form',
text: content
};

transporter.sendMail(mail, (err, data) => {
if (err) {
console.log(err);
res.json({
status: 'fail'
});
} else {
console.log('Email sent successfully');
res.json({
status: 'success'
});
}
});
});

app.listen(3003);

[/CODE]

[CODE lang="javascript" title="config.js" highlight="2"]module.exports = {
USER: 'my-email@gmail.com',
PASS: 'aaaa bbbb cccc dddd'
}[/CODE]
 
Technology news on Phys.org
Have you tried "ping example.com"? You may not have the applicable DNS. Or does your program need to know how to access DNS?
 
  • Like
Likes   Reactions: Darkmisc
There is an error in the code you copied. This:
[CODE lang="javascript" title="index.js"]var mail = {
from: name,
to: 'my-email@gmail.com',
subject: 'New Message from Contact Form',
text: content
};[/CODE]
most likely should be this:
[CODE lang="javascript" title="index.js"]var mail = {
from: email,
to: 'my-email@gmail.com',
subject: 'New Message from Contact Form',
text: content
};[/CODE]
or maybe:
[CODE lang="javascript" title="index.js"]var mail = {
from: '"' + name + '" <' + email + '>',
to: 'my-email@gmail.com',
subject: 'New Message from Contact Form',
text: content
};[/CODE]
There is an example on the Nodemailer website front page.

Since you have no email in the From header, I would bet that one of the imported modules (or another program processing the mail afterward) fills in the missing email. (The domain example.com doesn't accept emails.)

Unrelated, this also should be changed:
[CODE lang="javascript" title="index.js"]var transport = {
host: 'smtp.gmail.com',
port: 465,
secure: true,
auth: {
user: 'my-email@gmail.com',
pass: 'aaaa bbbb cccc dddd'
}
};[/CODE]
to:
[CODE lang="javascript" title="index.js"]var transport = {
host: 'smtp.gmail.com',
port: 465,
secure: true,
auth: {
user: creds.USER,
pass: creds.PASS
}
};[/CODE]
 
  • Like
Likes   Reactions: Darkmisc
Svein said:
Have you tried "ping example.com"? You may not have the applicable DNS. Or does your program need to know how to access DNS?
This is the first contact form I've tried making. What does pinging mean?

I've tested it with https://www.gmass.co/smtp-test and the test email came through.
 
jack action said:
There is an error in the code you copied. This:
[CODE lang="javascript" title="index.js"]var mail = {
from: name,
to: 'my-email@gmail.com',
subject: 'New Message from Contact Form',
text: content
};[/CODE]
most likely should be this:
[CODE lang="javascript" title="index.js"]var mail = {
from: email,
to: 'my-email@gmail.com',
subject: 'New Message from Contact Form',
text: content
};[/CODE]
or maybe:
[CODE lang="javascript" title="index.js"]var mail = {
from: '"' + name + '" <' + email + '>',
to: 'my-email@gmail.com',
subject: 'New Message from Contact Form',
text: content
};[/CODE]
There is an example on the Nodemailer website front page.

Since you have no email in the From header, I would bet that one of the imported modules (or another program processing the mail afterward) fills in the missing email. (The domain example.com doesn't accept emails.)

Unrelated, this also should be changed:
[CODE lang="javascript" title="index.js"]var transport = {
host: 'smtp.gmail.com',
port: 465,
secure: true,
auth: {
user: 'my-email@gmail.com',
pass: 'aaaa bbbb cccc dddd'
}
};[/CODE]
to:
[CODE lang="javascript" title="index.js"]var transport = {
host: 'smtp.gmail.com',
port: 465,
secure: true,
auth: {
user: creds.USER,
pass: creds.PASS
}
};[/CODE]
I've replaced the "from" field with email and "' + name + '" <' + email + '>', and neither work.

I also tried hardcoding the "from" field. Oddly enough, it just uses whatever I enter into the form.


I think the example from Nodemailer is the same as what's in the code, except for the highlighted lines (I kept the settings for gmail instead of using ethereal).

[CODE lang="javascript" title="transporter.sendMail" highlight="2-8"] transporter.sendMail(mail, (err, data) => {
if (err) {
res.json({
status: 'fail'
})
} else {
res.json({
status: 'success'

})

}
})[/CODE]
 
Another thing, in your render() function, all your inputs should have a name attribute with the value you set for your id attributes.

https://react.dev/reference/react-dom/components/input#reading-the-input-values-when-submitting-a-form said:
Give a name to every <input>, for example <input name="firstName" defaultValue="Taylor" />. The name you specified will be used as a key in the form data, for example { firstName: "Taylor" }.
 
  • Like
Likes   Reactions: Darkmisc
Darkmisc said:
This is the first contact form I've tried making. What does pinging mean?
Do you know how to open a Command Prompt on your computer?

Do so, and then type ping example.com:

Bad ping:
1716258628583.png

Good ping:
1716258849404.png
 
  • Like
Likes   Reactions: Darkmisc
DaveC426913 said:
Do you know how to open a Command Prompt on your computer?

Do so, and then type ping example.com:

Bad ping:
View attachment 345645
Good ping:
View attachment 345647
I get this for example.com
[CODE title="example ping"]Pinging example.com [93.184.215.14] with 32 bytes of data:
Reply from 93.184.215.14: bytes=32 time=167ms TTL=53
Reply from 93.184.215.14: bytes=32 time=168ms TTL=53
Reply from 93.184.215.14: bytes=32 time=168ms TTL=53
Reply from 93.184.215.14: bytes=32 time=167ms TTL=53

Ping statistics for 93.184.215.14:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 167ms, Maximum = 168ms, Average = 167ms[/CODE]

And this for gmail.com

[CODE title="gmail ping"]Pinging gmail.com [142.250.70.229] with 32 bytes of data:
Reply from 142.250.70.229: bytes=32 time=7ms TTL=60
Reply from 142.250.70.229: bytes=32 time=7ms TTL=60
Reply from 142.250.70.229: bytes=32 time=7ms TTL=60
Reply from 142.250.70.229: bytes=32 time=9ms TTL=60

Ping statistics for 142.250.70.229:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 7ms, Maximum = 9ms, Average = 7ms[/CODE]
 
jack action said:
Another thing, in your render() function, all your inputs should have a name attribute with the value you set for your id attributes.
This is not necessary, the OP is not using form.data (although it would of course be possible to rewrite the code to use that, and then they wouldn't need to have event handlers for each of the <input>s).
Svein said:
Have you tried "ping example.com"? You may not have the applicable DNS. Or does your program need to know how to access DNS?
This is not going to help: the only external domain that the server script accesses is smtp.gmail.com and it is clear that something is getting through to the SMTP service because the OP's gmail inbox contains an error report.

In my experience the best way of debugging is to insert debugging code so you can see what is actually going on (I believe I have given similar advice to the OP before).

The first step should have been to insert the indicated line below:
[code lang=javascript title=index.js]
transporter.sendMail(mail, (err, data) => {
if (err) {
console.log(err);
res.json({
status: 'fail'
});
} else {
console.log('Email sent successfully');
// Inserted to show what is going on:
console.log(data);
res.json({
status: 'success'
});
}
});
});
[/code]
 
  • #10
pbuk said:
The first step should have been to insert the indicated line below:

And if that didn't help, visit the Nodemailer page to find the following options:
[code lang=javascript title=index.js]
// var transport = {
// Don't use var, it's 2024.
// https://medium.com/@codingsam/awesome-javascript-no-more-var-working-title-999428999994
const transport = {
// Debugging (see https://www.nodemailer.com/smtp/).
logger: true,
debug: true,
host: 'smtp.gmail.com',
port: 465,
secure: true,
auth: {
user: 'my-email@gmail.com',
pass: 'aaaa bbbb cccc dddd'
}
};
[/code]

If you want to become a programmer you need to learn how to work with all the methods and tools that programmers use, including debugging and documentation.

Patching together code from tutorials (in this case it looks like some very old tutorials) and then posting here so that we have to debug your code and read the documentation will not help you in the long run.
 
  • #11
pbuk said:
If you want to become a programmer you need to learn how to work with all the methods and tools that programmers use, including debugging and documentation.
I strongly agree!