'My contact form isn't working with Nodemailer. How do I fix it?
I'm trying to implement email functionality with Node.js, React.js, Nodemailer, and OAuth2 on a contact form
I have two files:
contactForm.js
import React, { useState } from "react";
const App = () => {
const [mailerState, setMailerState] = useState({
name: "",
email: "",
subject:"",
message: "",
});
function handleStateChange(e) {
setMailerState((prevState) => ({
...prevState,
[e.target.name]: e.target.value,
}));
}
const submitEmail = async (e) => {
e.preventDefault();
console.log({ mailerState });
const response = await fetch("/api/server", {
method: "POST",
headers: {
"Content-type": "application/json",
},
body: JSON.stringify({ mailerState }),
})
.then((res) => res.json())
.then(async (res) => {
const resData = await res;
console.log(resData);
if (resData.status === "success") {
alert("Message Sent");
} else if (resData.status === "fail") {
alert("Message failed to send");
}
})
.then(() => {
setMailerState({
name: "",
email: "",
subject:"",
message: "",
});
});
};
return (
<div className="flex justify-center mb-14">
<form className="w-full max-w-lg" onSubmit={submitEmail} >
<div className="flex flex-wrap -mx-3 mb-6">
<div className="w-full md:w-1/2 px-3 mb-6 md:mb-0">
<label
htmlFor="name"
className="block uppercase tracking-wide text-gray-400 text-xs font-bold mb-2"
>
First Name
</label>
<input
className="appearance-none block w-full bg-gray-200 text-gray-700 border border-gray-200 rounded py-3 px-4 mb-3 leading-tight focus:outline-none focus:bg-white"
name="name"
type="text"
placeholder="Ade"
required value={mailerState.name}
onChange={handleStateChange}
/>
</div>
<div className="w-full md:w-1/2 px-3">
<label
htmlFor="name"
className="block uppercase tracking-wide text-gray-400 text-xs font-bold mb-2"
>
Last Name
</label>
<input
className="appearance-none block w-full bg-gray-200 text-gray-700 border border-gray-200 rounded py-3 px-4 leading-tight focus:outline-none focus:bg-white focus:border-gray-500"
name="lastname"
type="text"
placeholder="Banjo"
required value={mailerState.name}
onChange={handleStateChange}
/>
</div>
</div>
<div className="flex flex-wrap -mx-3 mb-6">
<div className="w-full px-3">
<label
htmlFor="email"
className="block uppercase tracking-wide text-gray-400 text-xs font-bold mb-2"
>
E-mail
</label>
<input
className="appearance-none block w-full bg-gray-200 text-gray-700 border border-gray-200 rounded py-3 px-4 mb-3 leading-tight focus:outline-none focus:bg-white focus:border-gray-500"
name="email"
type="email"
aria-describedby="emailHelp"
required value={mailerState.email}
onChange={handleStateChange}
/>
<p className="text-gray-600 text-xs italic">
e.g. [email protected]
</p>
</div>
</div>
<div className="flex flex-wrap -mx-3 mb-6">
<div className="w-full px-3">
<label
htmlFor="message"
className="block uppercase tracking-wide text-gray-400 text-xs font-bold mb-2"
>
Message
</label>
<textarea
className=" no-resize appearance-none block w-full bg-gray-200 text-gray-700 border border-gray-200 rounded py-3 px-4 mb-3 leading-tight focus:outline-none focus:bg-white focus:border-gray-500 h-48 resize-none"
name="message"
required value={mailerState.message}
onChange={handleStateChange}
></textarea>
<p className="text-gray-600 text-xs italic">
</p>
</div>
</div>
<div className="md:flex md:items-center">
<div className="md:w-1/3">
<button
className="shadow bg-indigo-600 hover:bg-indigo-700 focus:ring-indigo-500 focus:ring-offset-indigo-200 text-white w-full transition ease-in duration-200 text-center font-bold py-2 px-1 rounded"
type="button"
>
Send
</button>
</div>
<div className="md:w-2/3"></div>
</div>
</form>
</div>
);
}
export default App;
and
server.js:
const express = require("express");
const app = express();
const nodemailer = require("nodemailer");
const cors = require("cors");
require("dotenv").config();
// middleware
app.use(express.json());
app.use(cors());
// Setting up SMTP for Nodemailer to send mail
const transporter = nodemailer.createTransport({
service: "gmail",
auth: {
type: "OAuth2",
user: process.env.EMAIL,
pass: process.env.WORD,
clientId: process.env.OAUTH_CLIENTID,
clientSecret: process.env.OAUTH_CLIENT_SECRET,
refreshToken: process.env.OAUTH_REFRESH_TOKEN,
},
});
// verify connection configuration
transporter.verify(function (error, success) {
if (error) {
console.log(error);
} else {
console.log(`=== Server is ready to take our messages: ${success} ===`);
}
});
app.post("/api/server", function (req, res) {
let mailOptions = {
from: `${req.body.mailerState.email}`,
to: process.env.EMAIL,
subject: `Message from: ${req.body.mailerState.email}`,
text: `${req.body.mailerState.message}`,
};
transporter.sendMail(mailOptions, function (err, data) {
if (err) {
res.json({
status: "fail",
});
} else {
console.log("== Message Sent ==");
res.json({
status: "success",
});
}
});
});
const port = 5000;
app.listen(port, () => {
console.log(`Server is running on port: ${port}`);
});
They are both in two different folders: contactForm.js is in Components folder and server.js is in pages/api folder.
The Contact form renders perfectly but the email functionality does not. How do I resolve this?
Thanks in advance
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
