DEV Community

Cover image for Building a Super Cool Contact Form That Actually Sends Emails πŸš€βœ‰οΈ
Fred
Fred

Posted on

1 1

Building a Super Cool Contact Form That Actually Sends Emails πŸš€βœ‰οΈ

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
Enter fullscreen mode Exit fullscreen mode

Next, we grab some necessary dependencies:

npm install express nodemailer body-parser multer dotenv
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode
const app = express();
const upload = multer();

app.use(express.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(upload.none());
Enter fullscreen mode Exit fullscreen mode
  • express.json() : parses incoming requests with JSON payloads.
  • bodyParser.urlencoded({ extended: true }): parses URL-encoded data(tyically used in HTML forms).
  • upload.none(): tells muter 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"));
Enter fullscreen mode Exit fullscreen mode
// 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,
  },
});
Enter fullscreen mode Exit fullscreen mode
// 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");
  }
});
Enter fullscreen mode Exit fullscreen mode

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}`);
});
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

A snippet of what our HTML code looks like on a browser:
An image of a webpage with a contact form with name, email, subject, message fields and a submit button

Time to Test! πŸ•ΉοΈ

Run below commands in your terminal:

node server.js
Enter fullscreen mode Exit fullscreen mode

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

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

Top comments (1)

Collapse
 
githaiga22 profile image
Allan Githaiga β€’

What an educative blog post with node.js that demonstrates form creation...Thank you for sharing your valuable knowledge

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

πŸ‘‹ Kindness is contagious

Please leave a ❀️ or a friendly comment on this post if you found it helpful!

Okay