Just hit this obstacle, and in my case it was due to AngularJS. It's not limited to Angular, any library which binds the elements after page load can cause the Google reCAPTCHA to not show up since the element just does not exist by the time Google's code is being executed.
To solve this, first make the render explicit and supply a function to execute when the reCAPTCHA loads:
<script src='https://www.google.com/recaptcha/api.js?onload=recaptchaOnload&render=explicit' async defer></script>
Now, add a unique ID to the container, e.g.
<div id="recaptcha" class="g-recaptcha" data-sitekey="site key here"></div>
Then in the custom function wait for the element to actually exist:
var _captchaTries = 0;
function recaptchaOnload() {
_captchaTries++;
if (_captchaTries > 9)
return;
if ($('.g-recaptcha').length > 0) {
grecaptcha.render("recaptcha", {
sitekey: 'site key here',
callback: function() {
console.log('recaptcha callback');
}
});
return;
}
window.setTimeout(recaptchaOnload, 1000);
}
This will keep trying for 10 seconds, until it finds the element, then render the reCAPTCHA into it.