Adding reCAPTCHA to Secure Your Next.js Contact Form
In my last post, I walked through the steps of creating a contact form with Next.js and Nodemailer for email handling. However, as I continued to test it, I realized I hadn't considered spam prevention. This opened my inbox to potential spam attacks by bots. To tackle this, I integrated Google reCAPTCHA into the form, and I'll walk you through the process.
Google reCAPTCHA is a service that protects your site from bots by ensuring that the user interacting with your form is human. It’s easy to implement and very effective at blocking unwanted automated submissions.
Get reCAPTCHA keys from Google
First, you need to obtain your site key and secret key from Google. Head over to the reCAPTCHA admin console and register your site. Choose reCAPTCHA v2 or v3 depending on your preference (I’ll be using v2 checkbox in this example). After registration, you'll receive your site key and secret key.
Install react-google-recaptcha We'll need a library to embed reCAPTCHA in our Next.js form. Run:
npm install react-google-recaptcha
Add reCAPTCHA to the Contact Form
Modify your Contact.tsx file to include reCAPTCHA. We'll import ReCAPTCHA from the installed library, and place the component right above the submit button.
import ReCAPTCHA from "react-google-recaptcha";
const Contact = () => {
const [captchaValue, setCaptchaValue] = useState<string | null>(null);
const handleCaptchaChange = (value: string | null) => {
setCaptchaValue(value);
};
const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
if (!captchaValue) {
alert('Please complete the CAPTCHA');
return;
}
const mail: Email = { email, subject, message };
// rest of your code for submitting the form
};
return (
<form onSubmit={handleSubmit}>
{/* form fields */}
<ReCAPTCHA
sitekey={process.env.NEXT_PUBLIC_RECAPTCHA_SITE_KEY || ""}
onChange={handleCaptchaChange}
/>
<Button type="submit">Send message</Button>
</form>
);
};
Validate reCAPTCHA on the Server
In your api/send-email.ts, you'll now verify the reCAPTCHA token server-side using the secret key you received from Google. This ensures that the request came from a human.
import axios from 'axios';
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method === 'POST') {
const { email, subject, message, token } = req.body;
// Verify the reCAPTCHA token with Google
const verificationURL = `https://www.google.com/recaptcha/api/siteverify?secret=${process.env.RECAPTCHA_SECRET_KEY}&response=${token}`;
const { data } = await axios.post(verificationURL);
if (!data.success) {
return res.status(400).json({ error: 'reCAPTCHA verification failed' });
}
// Proceed with sending the email
}
}
Make sure to update the form submission code in Contact.tsx to send the reCAPTCHA token along with the email data:
const mail: Email = { email, subject, message, token: captchaValue };
Testing After setting this up, test your form to ensure reCAPTCHA is working correctly. You'll need to complete the reCAPTCHA challenge before submitting the form.
And that's it! You've successfully secured your Next.js contact form with reCAPTCHA to keep those pesky bots out of your inbox. Happy coding!
A passionate developer with 5+ years of experience in web development. Specializing in React, TypeScript, and modern JavaScript frameworks.
View all posts by Prince Shammah