This blog is part of a series where I document rebuilding a website that relies on HTML, CSS and Bootstrap in React.js using the Next.js framework to improve performance, reduce costs and increase my workflow for future changes.
The finished website: https://wallisconsultancy.co.uk
The source code: https://github.com/james-wallis/wallisconsultancy
What is EmailJS
In the previous blog I introduced EmailJS, a service designed to send emails on behalf of websites with no backend server, and added to the Wallis Consultancy React.js application that is being built.
What is reCaptcha
reCAPTCHA is a free service from Google that helps protect websites from spam and abuse. A “CAPTCHA” is a turing test to tell human and bots apart. It is easy for humans to solve, but hard for “bots” and other malicious software to figure out. By adding reCAPTCHA to a site, you can block automated software while helping your welcome users to enter with ease.
EmailJS supports Google reCaptcha verification before sending an email and you can restrict it to not send an email if a reCaptcha code is not sent in the request object.
For more detailed information see the topic on the EmailJS website: Adding CAPTCHA verification | EmailJS
Adding reCaptcha verification to EmailJS
An issue with the current wallisconsultancy.co.uk website is that the contact form can be easily abused by spam as it has no "human verification" method.
Let's fix this issue by adding Google reCaptcha support to the website.
Setting up reCaptcha
Creating a Google reCaptcha application
To setup EmailJS for my application we need to create a new application for Google reCaptcha.
To do this:
- Navigate to https://www.google.com/recaptcha
- Select
admin console
in the top right of the screen. - Select
register a new site
- Fill in the details
- Make sure you select
reCAPTCHA v2
as EmailJS does not supportv3
- I gave
localhost
as the site URL so that I can use it in development. It’s recommended that you keep your development and production reCaptcha separate so I created another application with wallisconsultancy.co.uk as the site URL.
- Make sure you select
Once you've done this you will be given a secret key
, keep this for the next step.
The Google reCaptcha sign up form
Connecting Google reCaptcha and EmailJS
Next, we need to configure EmailJS to require a reCaptcha verification before sending an email by adding the secret key generated in the previous step to CAPTCHA
tab of the EmailJS template section.
Adding the reCaptcha secret key to the EmailJS template
EmailJS is now configured so that it won't send emails without the reCaptcha code.
Adding reCaptcha to React
Let's modify the React application to send the reCaptcha code to EmailJS in the request object.
I'm using the react-google-recaptcha component to display the reCaptcha box. It supplies an onChange
function that has the reCaptcha code as a parameter.
I modified the flow of the contact form like so:
- User enters details
- On
send
the page changes to show the reCaptcha instead of the contact form - User completes reCaptcha and the
onChange
function is called. - React component combines the form values and reCaptcha code into a single
params
that is sent to EmailJS.
Example usage:
import emailjs from 'emailjs-com';
import ReCAPTCHA from 'react-google-recaptcha';
export default function MessageForm() {
// This should be implemented as a form
const [name, email, message] = ['name', 'email', 'message'];
const sendEmail = (captchaValue) => {
const params = {
...formState,
'g-recaptcha-response': captchaValue,
};
emailjs.send(
process.env.EMAIL_JS_SERVICE,
process.env.EMAIL_JS_TEMPLATE,
params,
process.env.EMAIL_JS_USER,
)
.then(({ status }) => {
console.log("EMAILJS SENT", status.code);
}, (err) => {
console.log("EMAILJS ERROR", err);
});
};
return (
<ReCAPTCHA
sitekey={process.env.CAPTCHA_SITE_KEY}
onChange={sendEmail}
/>
);
}
The complete code for the contact form on the Wallis Consultancy React application can be found on Github.
That's it, we've now setup an EmailJS powered contact form with Google reCaptcha so that we can safely deploy our application without the form being abused by bots to spam to the email recipient.
Round up
In this blog I’ve explored how reCaptcha can reduce the amount of spam sent from a contact form on a website and configured it to work with EmailJS.
In the next blog I will complete the development of wallisconsultancy.co.uk by using plugins to increase the performance of the website and the SEO score.
Top comments (9)
HI James,
In a Vue application I'm stuck with how to combine the form values and reCaptcha code into a single params that is sent to EmailJS. I guess what I basically need is your "Example usage" code for the React application written for a Vue application. Do you happen to have an equivalent code for Vue?
Simon
Hi Simon,
Unfortunately, I don't have the code for Vue but I've had a look on their docs and it looks to be the same. You should use the
.send
function documented here: emailjs.com/docs/sdk/send/. Then when calling the.send
function, add the field'g-recaptcha-response'
and the reCaptcha code into the params object.For example if you had a EmailJS template that required a
name
andmessage
you'd do the following adding in theg-recaptcha-response
:If you send me a link to your code or paste the relevant part as a comment I'm happy to take a look.
Thanks so much, James. I'll take a close look over your guidance and code tomorrow.
I said I was working on a Vue application but actually it's a Nuxt application. You'll understand I'm sure as I see you work with Next.js.
My code is here:
github.com/pastorsi/ghost-nuxt-web...
In the script section of that file, onSubmit for reCaptcha is not actioned because I couldn't get it working. I action EmailJS without reCaptcha.
(My repository is a working repository for a website. The working website contact form here mcea.org.uk/contact.)
All the best,
Simon
Monmouth, UK
No problem at all.
I’ve had a look your code and done a bit of research on Nuxt to understand it a bit better.
You’re using
.sendForm
and passing thee.target
as the third parameter. AFAIK Recaptcha only works with the.send
function.So this is what I’d suggest:
.sendForm
to be.send
g-recaptcha-response
.id=“form-name”
etc.document.getElementById()
. So the EmailJS parameter object and.send
function should roughly look like:I’ve not tested that code block but it should at least put you on the right track!
Let me know how you get on and if you need further assistance.
Thanks, James
To be honest, the captcha was made for
sendForm
method, since the captcha is usually part of the form. However, thesend
method can send any params, including the captcha token.By the way, this is why the name of the parameter is so strange (
g-recaptcha-response
), this is the default name from reCAPCHA.Ah is that right? I ended up using
send
as I wanted to show the reCaptcha after the form was submitted but before querying EmailJS.Additionally, I wasn't able to find a guide to use reCaptcha with
sendForm
whereas I could find one forsend
emailjs.com/docs/rest-api/send/. Looking again at the docs and your comment I guess that you literally just put the reCaptcha inside theform
element and EmailJS will get it out ofe.target
.Yeah, you guess correctly.
Hello @james et all,
I don't know if this thread is still active but I'm gonna try my luck anyways.
I have tried severally to make Emailjs work for me but it's not.
I am not much of a programmer, I am just a beginner but I want to do this myself and I believe with your help, I will get it done.
I have followed all the tutorials I saw online to my best understanding.
I want to make the form send notifications only when the recaptcha is solved correctly but I have no idea why it's not working.
I guess I am not getting somethings right and that is: prnt.sc/NU0o2vRNYewd is one of them.
How do I pass the g-recaptcha response?
Kindly have a look at my code: github.com/Olammyinc/supportrequest
Please note that I have the javascript files in a separate folder.
Thanks
Best regards.
👏