fbpx

Handle Multiple reCAPTCHA’s on the Same Page

reCAPTCHA’s default configuration hijacks pretty much everything about form submission. So anything you want to do with the form, such as validation, will need to be fired in the configured callback function, rather than on the traditional submit event.

This is pretty simple for most scenarios because you can use the form’s HTML ID to get a reference to the form in your callback, which Google demonstrates in their documentation:

<html>
  <head>
    <title>reCAPTCHA demo: Simple page</title>
     <script src="https://www.google.com/recaptcha/api.js" async defer></script>
     <script>
       function onSubmit(token) {
         document.getElementById("demo-form").submit(); // hard-coded form id
       }
     </script>
  </head>
  <body>
    <form id='demo-form' action="?" method="POST">
      <button class="g-recaptcha" data-sitekey="your_site_key" data-callback='onSubmit'>Submit</button>
      <br/>
    </form>
  </body>
</html>

Code language: HTML, XML (xml)

However, this falls apart if you have multiple forms on your page. You probably want to know exactly which form was submitted so that you can act on that form specifically. Google doesn’t document this scenario, so here’s how to do it.

Your Forms

<form action="/submit" method="POST">
	// some fields
	<input type="submit" class="g-recaptcha" data-sitekey="your-site-key" value="Submit">
</form>

<form action="/submit-2" method="POST">
	// some fields
	<input type="submit" class="g-recaptcha" data-sitekey="your-site-key" value="Submit">
</form>Code language: HTML, XML (xml)

Nearly identical, but not quite. Using the same key is supported, so that’s all fine and good. But we want to submit these forms to different endpoints, which means we need a reference to the form in our callback. To do this, we can pass an anonymous callback function when explicitly initializing our reCAPTCHAs. This isn’t documented well by Google, but you can do it!

<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit"
        async defer>
    </script>

var onloadCallback = function() {
	document.querySelectorAll('.g-recaptcha').forEach(function(el) {
		grecaptcha.render(el, {
			'sitekey': el.getAttribute('data-sitekey'),
			'callback': function() {
				var form = el.closest('form');
				// form.submit();
				// form.reportValidity();
				// myCustomCallback(form);
			},
		});
	});
}
Code language: PHP (php)

You’ll note we’ve also done this with vanilla Javascript.


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *