In this blog, we will learn how to integrate Google reCAPTCHA with a Next.js contact form to prevent spam submissions and enhance the security of the form.
Google reCAPTCHA is a free service provided by Google that helps protect websites from abusive activities by bots. By adding reCAPTCHA to our contact form, we can ensure that only human users can submit the form while reducing the chances of receiving spam.
Please refer to my previous blog on building a Contact Us form in Sitecore using Nextjs and Nodemailer.
Before proceeding, ensure that you have the following set up:
To use the ReCAPTCHA component, we need to install the react-google-recaptcha package. Run the following command in your project directory:
npm install react-google-recaptcha
In the component where you have implemented the contact form, add the reCAPTCHA widget to the form. Update your ContactUsForm.tsx component as follows:
//...(Existing imports)
import ReCAPTCHA from 'react-google-recaptcha';
//...(Sitecore fields)
const FORM_DEFAULT: {
[key: string]: string;
} = {
firstName: '',
lastName: '',
message: '',
captchaToken: '',
};
const ContactUsForm = ({ fields }: ContactUsFormProps): JSX.Element => {
const [formData, setFormData] = useState(FORM_DEFAULT);
const [successMsgCss, setSuccesssMsg] = useState(false);
// Create a ref for the reCAPTCHA widget
const recaptcha: RefObject<ReCAPTCHA> = useRef(null);
// ... (Existing functions)
const formSubmit = async (event: FormEvent<HTMLFormElement>) => {
event.preventDefault();
formData.recipient = fields.emailRecipient.value;
formData.emailSubject = fields.emailSubject.value;
fetch('/api/contact', {
method: 'POST',
headers: {
Accept: 'application/json, text/plain, */*',
'Content-Type': 'application/json',
},
body: JSON.stringify(formData),
})
.then((response) => {
console.log('response recieved');
if (response.status === 200) {
console.log('response succeeded');
setSuccesssMsg(true);
setFormData(FORM_DEFAULT);
recaptcha?.current?.reset();// reset recaptcha after submission
}
})
.catch((error) => {
console.error(error);
});
}
};
const onCaptchaChange = (token: string | null) => {
// Set the captcha token when the user completes the reCAPTCHA
if (token) {
formData.captchaToken = token;
}
};
return (
{/* ... (existing TSX markup) */}
<div className="pr-15px pl-25px pt-50px pb-25px mx-auto max-w-1200px w-full">
<div>
{/* ... (existing form fields) */}
{/* Add the reCAPTCHA widget */}
<div className="pb-20px">
<ReCAPTCHA
size="normal"
sitekey="YOUR_RECAPTCHA_SITE_KEY"
onChange={onCaptchaChange}
ref={recaptcha}
/>
</div>
{/* ... (existing submit button) */}
</form>
</div>
Update your API route (/pages/api/contact.ts) to validate the reCAPTCHA token received from the frontend:
//...existing imports
import axios from 'axios';
export default async function handler(req: NextApiRequest, res: NextApiResponse): Promise<void> {
// ... (existing transporter setup and mailData)
// Validate the reCAPTCHA token on the server-side
try {
const response = await axios.post(
`https://www.google.com/recaptcha/api/siteverify?secret=${process.env.RECAPTCHA_SECRET_KEY}&response=${req.body.captchaToken}`
);
if (response.data.success) {
//reCaptcha verification successfull
transporter.sendMail(mailData, function (err, info) {
if (err) {
console.log(err);
res.status(500).send('Internal Server Error');
} else {
console.log('successful');
console.log(info);
res.status(200).end();
}
});
} else {
// reCAPTCHA verification failed
res.status(400).send('reCAPTCHA verification failed.');
}
} catch (error) {
console.error(error);
res.status(500).send('Internal server error');
}
}
In this above code, we use axios.post to send a POST request to the Google reCAPTCHA API endpoint (https://www.google.com/recaptcha/api/siteverify). We pass the reCAPTCHA token and the reCAPTCHA secret key in the request body. The response contains the verification result, which we check to ensure the reCAPTCHA was successful. If the reCAPTCHA verification succeeds, we proceed with sending the email; otherwise, we return an error response.
In this blog post, we learned how to add Google reCAPTCHA to your existing Next.js contact form. By integrating reCAPTCHA, you can enhance the security of your form and prevent automated spam submissions. Implementing reCAPTCHA is a straightforward process and provides an added layer of protection for your website's forms.
Sign up to our bi-weekly newsletter for a bite-sized curation of valuable insight from the Sitecore community.