Last active
May 19, 2024 23:40
-
-
Save bramses/b060bae1cfee842bb72932981036dc32 to your computer and use it in GitHub Desktop.
Create a Contact Form in NextJS/Vercel
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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> | |
)} | |
</> | |
); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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