'Next.js how to implement react-google-recaptcha in my contact form
I am trying to implement Google Recaptcha on my contact form in Next.js. It does popup the challenge when needed, but sends the form anyway. Here's my code so far:
// Recaptcha
const recaptchaRef = useRef();
// Form validation
const [validated, setValidated] = useState(false);
// Reset form
const formRef = useRef();
const handleReset = () => {
formRef.current.reset();
setValidated(false);
};
// Thank you Message
const [thankYouMessage, setThankYouMessage] = useState(false);
// Form submit handler
async function handleSubmit(e) {
e.preventDefault();
e.stopPropagation();
// Execute the reCAPTCHA when the form is submitted
recaptchaRef.current.execute();
const formData = new FormData();
Array.from(e.currentTarget.elements).forEach((field) => {
if (!field.name) return;
formData.append(field.name, field.value);
});
await fetch(process.env.NEXT_PUBLIC_WORDPRESS_CF7_ENDPOINT, {
body: formData,
method: "POST",
})
.then((response) => response.json())
.then((response) => {
if (response.status === "mail_sent") {
setThankYouMessage(!thankYouMessage);
} else if (response.status === "mail_failed") {
alert("Message failed to send.");
}
});
setValidated(true);
handleReset();
recaptchaRef.current.reset();
}
And on the form:
<Form
ref={formRef}
validated={validated}
onSubmit={handleSubmit}
>
<ReCAPTCHA
ref={recaptchaRef}
size="invisible"
sitekey={process.env.NEXT_PUBLIC_RECAPTCHA_SITE_KEY}
/>
This of course does not work because it sends the form anyway even if the recaptcha gets triggered.
I've tried adding onChange={onReCAPTCHAChange}
on <ReCAPTCHA />
but then get an error Uncaught (in promise) ReferenceError
:
const onReCAPTCHAChange = (captchaCode) => {
// If the reCAPTCHA code is null or undefined indicating that
// the reCAPTCHA was expired then return early
if (!captchaCode) {
return;
}
// Else reCAPTCHA was executed successfully so proceed with the
// alert
alert(`Hey, ${email}`);
// Reset the reCAPTCHA so that it can be executed again if user
// submits another email.
recaptchaRef.current.reset();
};
Solution 1:[1]
I think in your handleSubmit you can use executeAsync
method like this (as shown in official documentation), this way you should be able to write everything in handleSubmit:
import ReCAPTCHA from "react-google-recaptcha";
const ReCAPTCHAForm = (props) => {
const recaptchaRef = React.useRef();
const handleSubmit = async () => {
try {
const token = await recaptchaRef.current.executeAsync();
// Add your API call code here also pass token to API
} catch(error) {
// handle validation error
}
}
return (
<form onSubmit={handleSubmit}>
<ReCAPTCHA
ref={recaptchaRef}
size="invisible"
sitekey="Your client site key"
/>
</form>
)
}
ReactDOM.render(
<ReCAPTCHAForm />,
document.body
);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Aks |