Skip to content

Instantly share code, notes, and snippets.

@bramses
Last active May 19, 2024 23:40
Show Gist options
  • Save bramses/b060bae1cfee842bb72932981036dc32 to your computer and use it in GitHub Desktop.
Save bramses/b060bae1cfee842bb72932981036dc32 to your computer and use it in GitHub Desktop.
Create a Contact Form in NextJS/Vercel
// frontend - react
import { useState } from "react";
import Alert from "@reach/alert";
export default function Contact() {
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const [message, setMessage] = useState("");
const [messageSent, setMessageSent] = useState(false);
const [messageCallout, setMessageCallout] = useState(
"📧 Message Sent! I'll get back to you soon."
);
const [sendInProgress, setSendInProgress] = useState(false);
const [hsla, setHsla] = useState("hsla(120, 96%, 88%, .85)");
const handleSubmit = (e) => {
e.preventDefault();
setSendInProgress(true);
fetch("/api/email", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
email: email,
name: name,
message: message,
}),
})
.then((res) => {
if (res.status !== 200) {
setMessageCallout("📧 Message Failed to Send! 😵");
setHsla("hsla(10, 50%, 50%, .10)");
}
setSendInProgress(false);
setMessageSent(true);
})
.catch((err) => {
console.log(err);
setMessageCallout("📧 Message Failed to Send! 😵");
setHsla("hsla(10, 50%, 50%, .10)");
setSendInProgress(false);
setMessageSent(true);
});
};
return (
<>
<h1>Talk To Me</h1>
<form onSubmit={handleSubmit}>
<label>
Name: (required)
<input
type="text"
required
placeholder="bram"
onChange={() => setName(event.target.value)}
/>
</label>
<br />
<br />
<label>
Email: (required)
<input
type="text"
required
placeholder="[email protected]"
onChange={() => setEmail(event.target.value)}
/>
</label>
<br />
<br />
<label>
Message: (required)
<textarea
type="text"
required
placeholder="What's on your mind?"
onChange={() => setMessage(event.target.value)}
/>
</label>
<br />
<br />
<input type="submit" value="Submit" />
</form>
<br />
{sendInProgress && <p>sending...</p>}
{messageSent && (
<Alert
style={{
background: hsla,
padding: "10px",
}}
>
<span>{messageCallout}</span>
</Alert>
)}
</>
);
}
// backend
// /api/email
import nodemailer from "nodemailer";
export default async function handler(req, res) {
console.log("-- sendEmail --");
if (req.method === "POST") {
// Process a POST request
const contactEmail = nodemailer.createTransport({
service: "gmail",
auth: {
user: process.env.EMAIL_USERNAME,
pass: process.env.EMAIL_PASSWORD,
},
});
await new Promise((resolve, reject) => {
// verify connection configuration
contactEmail.verify((error) => {
if (error) {
console.log(error);
reject(error);
} else {
console.log("Ready to Send");
resolve();
}
});
});
const email = req.body.email;
const name = req.body.name;
const message = req.body.message;
const mailOptions = {
from: `${name} <${email}>`,
to: process.env.EMAIL_USERNAME,
subject: "Contact Form Submission",
html: `<p><b>Name:</b> ${name}</p>
<p><b>Email:</b> ${email}</p>
<p><b>Message:</b> ${message}</p>`,
};
console.log(mailOptions);
await new Promise((resolve, reject) => {
// send mail
contactEmail.sendMail(mailOptions, function (error, info) {
if (error) {
console.log(error);
reject(error);
} else {
console.log("Email sent: " + info.response);
resolve(info);
}
});
});
res.statusCode = 200;
res.setHeader("Content-Type", "application/json");
res.end(
JSON.stringify({
status: "success",
})
);
} else {
// Handle any other HTTP method
res.statusCode = 404;
res.end("Not Found");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment