DEV Community

Cover image for How to use EmailJS for a Contact Us page
Olufeyimi Samuel
Olufeyimi Samuel

Posted on • Updated on

How to use EmailJS for a Contact Us page

I remember some time ago while working on a side project. I was to implement a simple contact us page as part of the project. Initially, I used Google Firebase to store the responses. Then, I found EmailJS and it was so simple to use and very efficient.

In this article, you will learn how to set up a EmailJS account and integrate it into your ReactJS/NextJS application.

First, let’s start by creating a new React Project using Vite.
Open your VSCode or any other code editor, open the terminal and type in:
yarn create vite or npm create vite@latest then follow the prompts. I will be using React with Typescript in this example.

You can checkout the official vite website for more information on Vite.

Next, let’s install some dependencies. In your terminal, type in yarn add @emailjs/browser react-hook-form. Then run yarn dev to start the project.
You can get more info on react-hook-form here

I will delete some default files in the directory and change some styles as seen below.

Project directory

Next, in my App.tsx, I will put up a basic contact us form.

import styles from "./app.module.css";
import { useForm } from "react-hook-form";
import { useState } from "react";

interface IFormInput {
  firstName: string;
  lastName: string;
  email: string;
  phone: string;
  message: string;
}
function App() {
  const [loading, setLoading] = useState(false);

  const {
    register,
    handleSubmit,
    reset,
    formState: { errors },
  } = useForm<IFormInput>();
  const onSubmit = async (data: IFormInput) => {
    console.log(data);
  };

  return (
    <div className={styles.contact_form}>
      <h1>Contact Form</h1>
      <p>Our friendly team would love to hear from you.</p>

      <form className={styles.form} onSubmit={handleSubmit(onSubmit)}>
        <div className={styles.group}>
          <div className={styles.input_group}>
            <label htmlFor="firstName">First Name</label>
            <input
              type="text"
              {...register("firstName", { required: true })}
              placeholder="Enter your first name"
            />
            {errors.firstName && (
              <span className={styles.error}>This field is required</span>
            )}
          </div>
          <div className={styles.input_group}>
            <label htmlFor="lastName">Last Name</label>
            <input
              type="text"
              {...register("lastName", { required: true })}
              placeholder="Enter your last name"
            />
            {errors.lastName && (
              <span className={styles.error}>This field is required</span>
            )}
          </div>
        </div>
        <div className={styles.input_group}>
          <label htmlFor="email">Email Address</label>
          <input
            type="email"
            {...register("email", { required: true })}
            placeholder="Enter your email address"
          />
          {errors.email && (
            <span className={styles.error}>This field is required</span>
          )}
        </div>
        <div className={styles.input_group}>
          <label htmlFor="phone">Phone Number</label>
          <input
            type="tel"
            {...register("phone", { required: true })}
            placeholder="+2348123456789"
          />
          {errors.phone && (
            <span className={styles.error}>This field is required</span>
          )}
        </div>
        <div className={styles.input_group}>
          <label htmlFor="message">Message</label>
          <textarea
            {...register("message", { required: true })}
            placeholder="Leave us a message..."
          />
          {errors.message && (
            <span className={styles.error}>This field is required</span>
          )}
        </div>

        <button disabled={loading} className={styles.button} type="submit">
          {loading ? "Sending..." : "Send Message"}
        </button>
      </form>
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

In the code snippet above, I’m using CSS module for my component alongside react-hook-form for my form validation. I declared a loading state set to false by default.

Next, I want to go to the official EmailJS website and signup for a free account. The signup is straightforward.

EmailJS website

Next, I will sign in to my account and setup a new email service. For this example, we will use only Gmail. On your dashboard, select Add New Service and select Gmail. Then select Connect Service. This will take you to your Gmail account to link together with Emailjs. Once done, select Create Service.

Add New Service

Gmail Service

Connect and Create Service

Next, we need to create an Email Template. On your dashboard, select Email Templates and select Create New Template. For the free version, you can only create 2 Email Templates.

New Template

You can configure your Email Template as you want.

Configure Template

In the image above, template body corresponds with the payload I’m sending from my app. You should also specify the receiver email and you can add extra Bcc and CC.

Next, we need to get 3 important credentials. The service ID, the template ID and your public key.

To get the template ID, navigate to the settings tab of the template and you will find the template key. You can as well modify the template name here.

Template ID

Next, go to the Email Services screen and you will find the service ID for the service we connected earlier.

Service ID

Next, go to Account and under the General tab, you will find your public and private keys. We only need the public key.

Public and Private key

Lastly, we go back to our code and update our onSubmit function and integrate emailjs into our code.
To do this, in your App.tsx, import emailjs from "@emailjs/browser";

Then modify your onSubmit function as follow:

onSubmit Function

Finally, your App.tsx should look like this:

import styles from "./app.module.css";
import { useForm } from "react-hook-form";
import { useState } from "react";
import emailjs from "@emailjs/browser";

interface IFormInput {
  firstName: string;
  lastName: string;
  email: string;
  phone: string;
  message: string;
}
function App() {
  const [loading, setLoading] = useState(false);

  const {
    register,
    handleSubmit,
    reset,
    formState: { errors },
  } = useForm<IFormInput>();
  const onSubmit = (data: IFormInput) => {
    setLoading(true);

    const templateParams = {
      ...data,
    };

    emailjs
      .send(
        "your_service_id",
        "your_template_id",
        templateParams,
        "your_public_key"
      )
      .then(() => {
        reset();
        setLoading(false);
        alert("One of our agents will contact you soon!");
      });
  };

  return (
    <div className={styles.contact_form}>
      <h1>Contact Form</h1>
      <p>Our friendly team would love to hear from you.</p>

      <form className={styles.form} onSubmit={handleSubmit(onSubmit)}>
        <div className={styles.group}>
          <div className={styles.input_group}>
            <label htmlFor="firstName">First Name</label>
            <input
              type="text"
              {...register("firstName", { required: true })}
              placeholder="Enter your first name"
            />
            {errors.firstName && (
              <span className={styles.error}>This field is required</span>
            )}
          </div>
          <div className={styles.input_group}>
            <label htmlFor="lastName">Last Name</label>
            <input
              type="text"
              {...register("lastName", { required: true })}
              placeholder="Enter your last name"
            />
            {errors.lastName && (
              <span className={styles.error}>This field is required</span>
            )}
          </div>
        </div>
        <div className={styles.input_group}>
          <label htmlFor="email">Email Address</label>
          <input
            type="email"
            {...register("email", { required: true })}
            placeholder="Enter your email address"
          />
          {errors.email && (
            <span className={styles.error}>This field is required</span>
          )}
        </div>
        <div className={styles.input_group}>
          <label htmlFor="phone">Phone Number</label>
          <input
            type="tel"
            {...register("phone", { required: true })}
            placeholder="+2348123456789"
          />
          {errors.phone && (
            <span className={styles.error}>This field is required</span>
          )}
        </div>
        <div className={styles.input_group}>
          <label htmlFor="message">Message</label>
          <textarea
            {...register("message", { required: true })}
            placeholder="Leave us a message..."
          />
          {errors.message && (
            <span className={styles.error}>This field is required</span>
          )}
        </div>

        <button disabled={loading} className={styles.button} type="submit">
          {loading ? "Sending..." : "Send Message"}
        </button>
      </form>
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

And that is it. You can now get new contact us messages directly in the receiver email you specified.

Thank you for reading. If this was helpful, leave a like.

Top comments (2)

Collapse
 
bomarto5m1m0 profile image
Anis Rb

Very helpful and this code feels so good to read well organized and explained thanks !

Collapse
 
william33199979 profile image
Williams Alex

Nice one Boss