Contact form with NextJS and SendGrid

Back to Blogs
Contact form with NextJS and SendGrid

Today I will show you how you can send emails for free with Sendgrid.

First, you need a SendGrid account. Go to signup.sendgrid.com to create one. Then generate an API KEY.

Sendgrid requires you to authenticate yourself (email account) from which you want the emails to be sent. Go to  Sender Authentication page. Then create a new sender. Fill out all your details. Verify by checking the email you will receive from sendgrid.

Then add Env variable in next.js application .env file for SendGrid API KEY.

SEND_GRID_TOKEN=jdiwjd9wud92bB55y3TD6d22dA6ZG2d2gJ97gA

Then install the @sendgrid/mail package

npm install @sendgrid/mail

Then go pages > api folder and create a file sendgrid.js

import sendgrid from "@sendgrid/mail";

sendgrid.setApiKey(process.env.SEND_GRID_TOKEN);

export default async (req, res) => {
  try {
    await sendgrid.send({
      to: "your_email@gmail.com",
      from: "your_email_you_verify_in_sendgrid@something.com",
      subject: "Contact form email",
      html: `<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      <html lang="en">
      <head>
        <meta charset="utf-8">

        <title>The HTML5 Herald</title>
        <meta name="description" content="The HTML5 Herald">
        <meta name="author" content="SitePoint">
      <meta http-equiv="Content-Type" content="text/html charset=UTF-8" />

        <link rel="stylesheet" href="css/styles.css?v=1.0">

      </head>

      <body>
        <div class="img-container" style="display: flex;justify-content: center;align-items: center;border-radius: 5px;overflow: hidden; font-family: 'helvetica', 'ui-sans';">
              </div>
              <div class="container" style="margin-left: 20px;margin-right: 20px;">
              <b>From:</b> ${req.body.name} <br /> 
              <b>Email:</b> ${req.body.email} <br />
              <b>Number:</b> ${req.body.number} <br /> 
              <b>Subject:</b> ${req.body.subject} <br /> 
              <b>Message:</b> ${req.body.text} 
              </div>
              </div>
      </body>
      </html>`,
    });
  } catch (error) {
    return res.status(error.statusCode || 500).json({ error: error.message });
  }

  return res.status(200).json({ error: "" });
};

You can change to, from, subject, HTML with what you want.

If you want to have a popup with confirmation you can install sweetalert2 package.

npm i sweetalert2

Then create a component ContactForm.js and add this:

import React, { useState } from "react";
import Swal from "sweetalert2";
import withReactContent from "sweetalert2-react-content";
const MySwal = withReactContent(Swal);

const alertContent = () => {
  MySwal.fire({
    title: "Congratulations!",
    text: "Your message was successfully send and will back to you soon",
    icon: "success",
    timer: 5000,
    timerProgressBar: true,
    showConfirmButton: false,
  });
};

// Form initial state
const INITIAL_STATE = {
  name: "",
  email: "",
  number: "",
  subject: "",
  text: "",
};

const ContactForm = () => {
  const [contact, setContact] = useState(INITIAL_STATE);

  const handleChange = (e) => {
    const { name, value } = e.target;
    setContact((prevState) => ({ ...prevState, [name]: value }));
  };

let baseUrl = your_domain_name;

  const handleSubmit = async (e) => {
    e.preventDefault();
    try {
      const url = `${baseUrl}/api/sendgrid`;
      const { name, email, number, subject, text } = contact;
      const payload = { name, email, number, subject, text };
      // const response = await axios.post(url, payload);
      const response = await fetch(url, {
        method: "POST",
        headers: {'Content-Type': 'application/json',},
        body: JSON.stringify(payload),
      });
      console.log(response);
      setContact(INITIAL_STATE);
      alertContent();
    } catch (error) {
      console.log(error);
    }
  };

  return (
    <div className="contact-form">
      <h2>Get In Touch</h2>

      <form onSubmit={handleSubmit}>
        <div className="container">
          <div className="row">
            <div className="col-lg-6">
              <div className="form-group">
                <input
                  type="text"
                  name="name"
                  placeholder="Name"
                  className="form-control"
                  value={contact.name}
                  onChange={handleChange}
                  required
                />
              </div>
            </div>
            <div className="col-lg-6">
              <div className="form-group">
                <input
                  type="text"
                  name="email"
                  placeholder="Email"
                  className="form-control"
                  value={contact.email}
                  onChange={handleChange}
                  required
                />
              </div>
            </div>
            <div className="col-lg-6">
              <div className="form-group">
                <input
                  type="text"
                  name="number"
                  placeholder="Phone number"
                  className="form-control"
                  value={contact.number}
                  onChange={handleChange}
                  required
                />
              </div>
            </div>
            <div className="col-lg-6">
              <div className="form-group">
                <input
                  type="text"
                  name="subject"
                  placeholder="Subject"
                  className="form-control"
                  value={contact.subject}
                  onChange={handleChange}
                  required
                />
              </div>
            </div>
            <div className="col-lg-12 col-md-12">
              <div className="form-group">
                <textarea
                  name="text"
                  cols="30"
                  rows="6"
                  placeholder="Write your message..."
                  className="form-control"
                  value={contact.text}
                  onChange={handleChange}
                  required
                />
              </div>
            </div>
            <div className="col-lg-12 col-sm-12">
              <button type="submit" className="btn btn-primary">
                Send Message
              </button>
            </div>
          </div>
        </div>
      </form>
    </div>
  );
};

export default ContactForm;

Change baseUrl with your domain name.

Now you can test it.

  • Category:
  • JavaScript