DEV Community

Allan Melo
Allan Melo

Posted on

Send emails from a contact form in React with EmailJS and Recaptcha

This post will guide you through the process of creating a "contact us" form in React.js, and then sending all the info by mail using a third-party service called EmailJS (https://www.emailjs.com/).


The component

First, you need to create a new file in your React codebase. I create it as ContactForm.jsx.

Import react and add emailJs as a dependency using yarn or npm.

yarn add emailjs-com --dev

I used Bulma as a framework to build the Contact Form in React (using the rbx lib), but all tags from rbx are sel-explained and can be easily replaced by other components and/or other frameworks you prefer.

import React from 'react';
import * as emailjs from 'emailjs-com';

import { Field, Label, Control, Input, Button, Icon, Textarea, Notification } from 'rbx';

class ContactForm extends React.PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      name: '',
      email: '',
      subject: '',
      message: ''
    };

    this.handleSubmit = this.handleSubmit.bind(this);
    this.resetForm = this.resetForm.bind(this);
    this.handleChange = this.handleChange.bind(this);
  }

  handleSubmit(event) {
    event.preventDefault();
    const { name, email, subject, message } = this.state;
    const templateParams = {
      from_name: name,
      from_email: email,
      to_name: '/*YOUR NAME OR COMPANY*/',
      subject,
      message_html: message,
    };
    emailjs.send(
      'gmail',
      'template_XXXXXXXX',
       templateParams,
      'user_XXXXXXXXXXXXXXXXXXXX'
    )
    this.resetForm();
  };

  resetForm() {
    this.setState({
      name: '',
      email: '',
      subject: '',
      message: '',
    });
  }

  handleChange(event) {
    this.setState({ [event.target.name]: event.target.value });
  }

  render() {
    const { name, email, subject, message, sentMessage } = this.state;

    return (
      <form onSubmit={this.handleSubmit}>
        <Field>
          <Label>Name</Label>
          <Control>
            <Input
              name="name"
              type="text"
              placeholder="Your first and last name"
              value={name}
              onChange={this.handleChange}
            />
          </Control>
        </Field>
        <Field>
          <Label>Email for contact</Label>
          <Control>
            <Input
              name="email"
              type="email"
              placeholder="email@gmail.com"
              value={email}
              onChange={this.handleChange}
            />
          </Control>
        </Field>
        <Field>
          <Label>Subject</Label>
          <Control>
            <Input
              name="subject"
              type="text"
              placeholder="What is the subject?"
              value={subject}
              onChange={this.handleChange}
            />
          </Control>
        </Field>
        <Field>
          <Label>Message</Label>
          <Control>
            <Textarea
              name="message"
              placeholder="Tell me more about..."
              value={message}
              onChange={this.handleChange}
            />
          </Control>
        </Field>

        <Field kind="group">
          <Control>
            <Button color="dark">Send</Button>
          </Control>
          <Control>
            <Button text>Cancel</Button>
          </Control>
        </Field>
      </form>
    );
  }
}

export default ContactForm;

Configuration

Create a free account on https://www.emailjs.com/ , connect your email service on it and get a very simple template. We need this to configure this component with your account data.

Inside the handler function on handleSubmit(event), you need to change the current "to_name" inside template params by your info. The other params (from_name, from_email, subject, and message_html) works very much like this.props, and can be easily retrieved on Emailjs website to build a template email with other infos you may want to get in your form. You can create your own params or take off those you don't need.

To use it on your template inside Emailjs, you just need to use curly braces inside the template builder.

Alt Text

Then, to send the email with this emailjs component, you need to change the configuration object in this function with your infos.

emailjs.send(
      'gmail',
      'template_XXXXXXXX',
       templateParams,
      'user_XXXXXXXXXXXXXXXXXXXX'
 )

The first parameter is your email service provider name. If you are using Gmail, then use "gmail". You can found it on email services tab.

email services

The second parameter is the template ID. You will get this from Dashboard of emailJs once registered.

Alt Text

The third parameter is variable templateParam which we created using entered data in the form. Don't change it.

The last parameter is the User ID in the emailJs dashboard.

Alt Text

Don't forget to create a template on EmailJS.

I recommend you to check the documentation if you need any help: https://www.emailjs.com/docs/


Extra: build it with Recaptcha!

EmailJS also works with Recaptcha, so you can also embed a Recaptcha verification in your form and protect it from robots or spammers by usign the React Recaptcha.

To make this works, you need to go to Recaptcha and get a SITE_KEY for you. Also, if you are testing it in your local env, don't forget to add "localhost" as a valid domain - so you can make all the test before going to production.

After that, go to EmailJS website and check your template. You will find a tab where you can activate the Recaptcha on it. You just need to follow their instructions to put your keys to work.

So ok... Now, how can we render this Recaptcha on our website?

To make Recaptcha works with React I found the react-recaptcha lib. For me, this was easy to work than the official react-recaptcha-google. So, just go for it and add this as a dependency:

yarn add react-recaptcha

To make it work properly, you need to add this fragment in the

of your original index.html, inside the public folder:
<script src="https://www.google.com/recaptcha/api.js" async defer></script>

Then put this piece where you want to render it:

<Recaptcha
  sitekey="YOUR_SITE_KEY"
   render="explicit"
    onloadCallback={this.recaptchaLoaded}
    verifyCallback={this.verifiedRecaptcha}
/>

Inside the constructor(props), add this:

recaptchaLoad: false,
isVerified: false,
/* and this... */
this.recaptchaLoaded = this.recaptchaLoaded.bind(this);
this.verifiedRecaptcha = this.verifiedRecaptcha.bind(this);

Then use these two elements inside your component to check if Recaptcha loaded and if the user checked it.

recaptchaLoaded() {
  this.setState({ recaptchaLoad: true });
}

verifiedRecaptcha(response) {
  if (response) {
    this.setState({ isVerified: true });
  }
}

I used both components to prevent the user to send an email without check the recaptcha, so you can change the handleSubmit(event) above by that one:

handleSubmit(event) {
    const { recaptchaLoad, isVerified } = this.state;
    event.preventDefault();
    if (recaptchaLoad && isVerified) {
      const { name, email, subject, message } = this.state;
      const templateParams = {
        from_name: name,
        from_email: email,
        to_name: '/*YOUR NAME OR COMPANY*/',
        subject,
        message_html: message,
      };
      emailjs.send(
        'gmail',
        'template_XXXXXXXX',
         templateParams,
        'user_XXXXXXXXXXXXXXXXXXXX'
      );
      alert('Your message has been sent successfully. We will contact you soon.');
      this.resetForm();
    } else {
      alert('Please check the Recaptcha before sending your message');
    }
  }

And that it!

I hope this post has helped you.

If it doesn’t render, after all the steps, it’s worth taking a look at the react-recaptcha documentation or the Google Recaptcha documentation, as the html element may have been modified.

This post was created based on this another one (https://medium.com/@eesh.t/send-email-using-emailjs-and-react-form-9993bb6929d8), but using Bulma as a framework and using Recaptcha to prevent abuse.

Top comments (1)

Collapse
 
markandersonnc profile image
MarkAndersonNC

Great info!