I’m trying to add reCAPTCHA V2 to all of the netlify forms on our HUGO-based website. (Note, I’m not the owner, just a lowly dev here.)
It seems like it’s definitely working sometimes, but then other times I get apparent errors. I think my test results (doing the same thing on the same pages) seems to produce one of 4 different results:
- I am not challenged by reCAPTCHA and I am immediately redirected to the form-success page. I think it is probably working as intended, since if reCAPTCHA doesn’t see me as suspicious, then I shouldn’t be challenged.
- I am challenged and I either succeed and get send to the form-success page, or I fail and am stopped from submitting the form at all. This also seems fine.
- I am not prompted and I sent straight to the form-success page, but it’s status 500 and I just get an error instead of seeing the page (clicking refresh or navigating to the page manually works every time though). In the case of number three my form data looks like this when I inspect the POST in dev tools:
form-name: contact
g-recaptcha-response:
txtName: Dan Testing12754
txtEmail: test@net.test
file: (binary)
bot-field:
txtMsg: This is just a test on a deploy preview.
btnSubmit: Send Message
And here is the request headers:
:authority: deploy-preview-1414--stagingjbm.netlify.app
:method: POST
:path: /form-success/
:scheme: https
accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
accept-encoding: gzip, deflate, br
accept-language: en-US,en;q=0.9
cache-control: max-age=0
content-length: 955
content-type: multipart/form-data; boundary=----WebKitFormBoundaryx5AT96aBkAHZmNAa
cookie: cart_jaquish=%5B%5D; _ga=GA1.2.1172870204.1600901590; _gid=GA1.2.41866906.1600901590; _omappvp=gLYfMkAOSndZYHwHqFCkm6W61uMu4DZiWnSDRNZMGqJTIeG0e1Mc5sqpFn2XR5lSjIVnbbIxsRDvTF9XUyYlWlvyhBNk2iUo; _omappvs=1600901589600; tracker_device=fd7f1332-8289-497a-b9d1-d6d0de24a5c4; _fbp=fb.1.1600901589914.519975691
origin: https://deploy-preview-1414--stagingjbm.netlify.app
referer: https://deploy-preview-1414--stagingjbm.netlify.app/contact/
sec-fetch-dest: document
sec-fetch-mode: navigate
sec-fetch-site: same-origin
sec-fetch-user: ?1
upgrade-insecure-requests: 1
user-agent: Googlebot/2.1
The response in turn is blank with status 500.
- I am challenged and I think succeed, but then the I still get a status 500 on the ‘form-success’ page
Here is a sample of form data submitted, as recorded by dev tools for one of these instances:
form-name: newsletter
bot-field:
email: test@foo.bar
title: Jaquish Biomedical
relpermalink: /
g-recaptcha-response: 03AGdBq26BYx9ATqr17AX6YXGz3xrh-131NNnmFZGxOrajQW04wmNnC2zDIRATBaOF7dNvfJ-ONB9dJCfN9HafuCVGASNIdAA44Yho0QMoCwDRDpbpz0nHJwENI2dF9KdZDmB9p_R3SODSZVUhbysSKoeTyQM7BzznYElc1ztghi3v9Sakozefbn0vEJYhtZeoESPevkKlMxQwD_giX26Uz_cE8ptP9ozqadFCQ9aBJuOSGocBsXCmW_-TxO8EGD-hRwy0tMqJP35xbTa53kXPCXN72aosv_ihzsTl6gu3aRh84SE59o2QWVOoVrE0pyf8D9JMeD5lM1oFB89tZQf_VgwcqxZClS8NcKAi2lVtsXoHaYUkD6pjjjGp0XDOJI_gW2FAb4jTAxBS2YE0d5DJEr74WKYjr9EBfuNqhnwtW2XkMkFUbf82Eq0jq1jUzHb3KdsdGwudmmRd0JcgEwmyNtfQk8JMReGdXzEOFEtYezQrr-neIStFd24
As you can see in this one, there is a valid captcha key, but still got status 500. The request headers for this one were identical to number 3.
It’s these number three and four cases that worry me. I don’t expect a form submit to work with a missing g-recaptcha-response, of course. However, from reading other posts and documentation I’m given to understand that I should receive a response with a status 303 for missing g-recaptcha-response. So getting a status 500 seems like a Netlify error, especially when the form submit should be a success. I’m not seeing any relevant console errors or warnings along with any of this either.
Here is a link to the deploy preview that I’m using right now:
https://deploy-preview-1414--stagingjbm.netlify.app/
Note that every page has a newsletter sign-up form in the footer. This usually the form I use for testing. Although reCAPTCHA should be hooking into all the forms on the entire site, so any form should work.
I’ve been opening chrome with a guest window in order to get reCAPTCHA to trigger, and when that doesn’t work, I used device emulation in dev tools with a custom user agent set to Googlebot/2.1
.
Here is the code I’m loading in the <head>
in order to dynamically generate the reCAPTCHA element for all forms on a given page:
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
<script defer>
// Set up callback function for submitting form after reCAPTCHA verification.
// We're setting and retrieving formToSubmit dynamically so that we know which of multiple forms to submit on a page
window.formToSubmit = null;
function submitActiveForm() {
try {
document.getElementsByClassName(window.formToSubmit)[0].submit();
} catch (e) {
console.error("Failed to submit form due to the following error");
console.error(e);
}
};
window.submitActiveForm = submitActiveForm; // Make sure the callback is in the global namespace
window.addEventListener("DOMContentLoaded", () => {
// Grab all forms on the page that are set up to submit via Netlify and use reCAPTCHA
const allForms = document.querySelectorAll("[data-netlify-recaptcha=true]");
let formCount = 0; // Used to provide a unique identifier to each form
// Set up reCAPTCHA for each form on the page
allForms.forEach((form) => {
// Add identifier to form
formCount++;
let formUniqueClass = `recaptcha-form-number-${formCount}`;
form.classList.add(formUniqueClass);
// Set up globally accessible function handle with bound context
window[`form${formCount}PreSubmit`] = (event) => {
window.formToSubmit = formUniqueClass;
event.preventDefault();
event.stopImmediatePropagation();
grecaptcha.execute();
};
// Create special google reCaptcha element to form
let reCaptchaDiv = document.createElement("div");
reCaptchaDiv.dataset.sitekey = {{.Site.Params.SITE_RECAPTCHA_KEY}}; // Google Recaptcha Public Site Key
reCaptchaDiv.dataset.size = "invisible"; // Required boilerplate
reCaptchaDiv.classList.add("g-recaptcha"); // Required boilerplate
reCaptchaDiv.dataset.callback = "submitActiveForm"; // Name of callback function as a string
// Append invisible reCAPTCHA element to form as second to last element
form.insertBefore(
reCaptchaDiv,
form.children[form.children.length - 1]
);
// Set up intercept for initial submit action and render reCAPTCHA element (if user is suspicious)
form.addEventListener("submit", window[`form${formCount}PreSubmit`]);
});
// Report that we're finished setting up reCAPTCHA listeners so that events.js can set up its listeners
window.reCaptchaReadyStatus = true;
const captchaReadyEvent = new Event("reCaptchaReady");
document.dispatchEvent(captchaReadyEvent);
});
</script>
Thanks for any help you may be able to provide!