Hey there, web dev enthusiasts! Ever wanted to create a contact form that doesn't just sit there looking pretty, but actually sends emails? Buckle up, because I'm about to show you how to build a contact form that'll make your portfolio website feel like a pro communication machine!
Prerequisites
- A sprinkle of Javascript magic
- A Gmail account. (because who doesn't have one?)
- Node.js and npm installed. Install here.
Step 1: Project Setup
Let’s start by creating a new Node.js project.
Type below on your terminal and run:
mkdir email-form-project
cd email-form-project
npm init -y
Next, we grab some necessary dependencies:
npm install express nodemailer body-parser multer dotenv
We'll check out what each one individually handles.
Step 2: The Secret Sauce- .env
File
Time to keep our secrets.. secret!We store our email credentials in an .env
file. This keeps sensitive data, like your Gmail credentials, out of the light, like a digital ninja.
EMAIL_USER=your-email@gmail.com
EMAIL_PASS=your-app-password
Set environment variables in the file .env
for Email
and App Password
. I used Google App passwords. Read about it here.
Step 3: Create the Server in server.js
We’ll set up an Express server and configure the route that handles form submissions. Inside server.js
add this code:
require("dotenv").config(); // module to load environment variables from .env file
const express = require("express"); // express is a webframework for Node.js
const nodemailer = require("nodemailer"); // nodemailer is a module to send emails
const bodyParser = require("body-parser"); // middleware to parse incoming request bodies
const path = require("path"); // handle file and directory paths
const multer = require("multer"); // middleware to manage form data
const app = express();
const upload = multer();
app.use(express.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(upload.none());
-
express.json()
: parses incoming requests with JSON payloads. -
bodyParser.urlencoded({ extended: true })
: parses URL-encoded data(tyically used in HTML forms). -
upload.none()
: tellsmuter
not to handle file uploads in the form, since there no file attachments.
// Serve the index.html file
app.get("/", (req, res) => {
res.sendFile(path.join(__dirname, "index.html"));
});
// Serve static files from the "static" folder
// Uncomment below code if you include css files, and images in your static folder
// app.use("/static", express.static("static"));
// Setting up Nodemailer Transporter
const transporter = nodemailer.createTransport({
host: "smtp.gmail.com",
port: 587, // specific port for non-secure SMTP communication
secure: false,
auth: {
user: process.env.EMAIL_USER,
pass: process.env.EMAIL_PASS,
},
});
// Handling POST requests and Sending emails
app.post("/submit", async (req, res) => {
const { name, email, subject, message } = req.body;
try {
const info = await transporter.sendMail({
from: `"${name}" <${email}>`,
to: `"your-name" <your-name@gmail.com>`, // Your target email address
subject: subject,
text: message,
html: `<b>${message}</b>`,
replyTo: `"${name}" <${email}>`,
});
console.log("Message sent: %s", info.messageId);
res.status(200).send("Email sent successfully!");
} catch (error) {
console.error("Error sending email: ", error);
res.status(500).send("Failed to send email");
}
});
transporter.sendMail()
is an asynchronous operation that could take some time. It behaves like a super-efficient assistant who can handle time-consuming tasks without making everything else wait in line!
More about async/await
here.
// Starting the Express Server
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
});
This sets up a simple Express server that:
- Serves an HTML form, accepts form submissions via a
POST
request. - Uses
Nodemailer
to send the form data as an email to a specified address.
Step 4: The HTML Form in index.html
Create an html form for our users to input their contact details.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Email Form</title>
</head>
<body>
<h1>Contact Us</h1>
<form action="/submit" method="POST">
<label for="name">Name:</label>
<input type="text" id="name" name="name" required><br><br>
<label for="email">Email:</label>
<input type="email" id="email" name="email" required><br><br>
<label for="subject">Subject:</label>
<input type="text" id="subject" name="subject" required><br><br>
<label for="message">Message:</label><br>
<textarea id="message" name="message" rows="4" required></textarea><br><br>
<button type="submit">Send Message</button>
</form>
</body>
</html>
A snippet of what our HTML code looks like on a browser:
Time to Test! 🕹️
Run below commands in your terminal:
node server.js
Open http://localhost:3000/ and BAM!. 💥 Your contact form is ready to send emails like a communication superhero!
Pro Tips
- Always use app passwords for Gmail
- Keep your
.env
file top-secret (add it to.gitignore
) - Test, test, and test again!
Ready to level up your portfolio website? Go forth and communicate! 🚀📧
Catch the full project on my GitHub: Project Link
Want to see it in action? Check out my portfolio: www.gitongacode.co.ke
Top comments (0)