42

I am using recaptcha v2

I am getting the following error occasionally (sometimes i don't get error and sometimes i do get it)

Uncaught ReferenceError: grecaptcha is not defined

It seems because of the internal http request. that takes some time to get another js recaptcha__en.js. Meanwhile actual rendering code of grecaptcha executes.

So what is the standard solution to avoid this issue.?

PS : of course i am looking for some solution other than setTimeout

9 Answers 9

38

Recaptcha has a onload callback that will run once recaptcha is loaded. Place your code inside that callback function.

https://developers.google.com/recaptcha/docs/display

<script>
    function onloadCallback() {
        /* Place your recaptcha rendering code here */
    }
</script>
<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit"></script>
11
  • 3
    but i want to render the captcha challenge not on pageload. i want to render it after user enters into some bootstrap modal
    – codeofnode
    Apr 23, 2015 at 11:53
  • @nodeofcode It is not page onload. This is provided by recaptcha. I have updated my answer with the example Apr 23, 2015 at 11:53
  • i do get your point.. but how can i render captcha into block which doesn't exists
    – codeofnode
    Apr 23, 2015 at 11:54
  • I didn't get what you meant by but how can i render captcha into block which doesn't exists ? Apr 23, 2015 at 11:56
  • grecaptcha.render(<somedivid>, paramObj) .. here somedivid need to exists in DOM in order that captcha renders into this div. Now If i provide onload query param, then the callback executes right after the scripts get loaded, and at that time i don't have that somedivid.
    – codeofnode
    Apr 23, 2015 at 11:58
6

I have solved this by ordering the script in below manner

HTML

<div id="review_recaptcha"></div>

jQuery

<script type="text/javascript">
      var review_recaptcha_widget;
      var onloadCallback = function() {
        if($('#review_recaptcha').length) {
            review_recaptcha_widget = grecaptcha.render('review_recaptcha', {
              'sitekey' : '<?php echo $site_key?>'
            });
        }
      };      
</script>
<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit" async defer></script>
0
4

It works on landing page and also in bootstrap 4 popup form:

<script src="https://www.google.com/recaptcha/api.js?render=ADD-YOUR-RECAPTCHA-SITE-KEY-HERE"></script>
<script>
var interval = setInterval(function(){
  if(window.grecaptcha){
        grecaptcha.ready(function() {
            grecaptcha.execute('ADD-YOUR-RECAPTCHA-SITE-KEY-HERE', {action: 'homepage'}).then(function(token) {
              $('#i-recaptcha').prepend('<input type="hidden" name="g-recaptcha-response" value="' + token + '">');
            });
        });
    clearInterval(interval);
  }
}, 100);
</script>

Thanks for asking this question. :)

3

My Problem got resolved by doing following changes in the script code (:

i.e from internal path

<script src='static/js/recaptcha/api.js'></script>

to external google path i.e

<script src='https://www.google.com/recaptcha/api.js'></script>

2

For me it was working for years then suddenly stopped.

switching the API load from

<script type="text/javascript" src="https://www.google.com/recaptcha/api.js"></script>

to having async and defer fixed it

<script type="text/javascript" src="https://www.google.com/recaptcha/api.js" async defer></script>
1

Sometimes the application loads several times the script 'https://www.google.com/recaptcha/api.js after refresh, make sure your application doesn't have multiple <script async="" defer="" src="https://www.google.com/recaptcha/api.js"></script>

1

If you don't want to use a callback, another async solution is explained in the recaptcha docs:

When loading reCAPTCHA asynchronously, keep in mind that reCAPTCHA cannot be used until it has finished loading. For example, the following code would likely break:

<script async src="https://www.google.com/recaptcha/api.js"></script>
<script>
  // If reCAPTCHA is still loading, grecaptcha will be undefined.
  grecaptcha.ready(function(){
    grecaptcha.render("container", {
      sitekey: "ABC-123"
    });
  });
</script>

In some situations, adjusting script ordering can be enough to prevent race conditions. Alternatively, you can prevent race conditions by including the following code snippet on pages that load reCAPTCHA. If you are using grecaptcha.ready() to wrap API calls, add the following code snippet to ensure that reCAPTCHA can be called at any time.

<script async src="https://www.google.com/recaptcha/api.js"></script>
<script>
  // How this code snippet works:
  // This logic overwrites the default behavior of `grecaptcha.ready()` to
  // ensure that it can be safely called at any time. When `grecaptcha.ready()`
  // is called before reCAPTCHA is loaded, the callback function that is passed
  // by `grecaptcha.ready()` is enqueued for execution after reCAPTCHA is
  // loaded.
  if(typeof grecaptcha === 'undefined') {
    grecaptcha = {};
  }
  grecaptcha.ready = function(cb){
    if(typeof grecaptcha === 'undefined') {
      // window.__grecaptcha_cfg is a global variable that stores reCAPTCHA's
      // configuration. By default, any functions listed in its 'fns' property
      // are automatically executed when reCAPTCHA loads.
      const c = '___grecaptcha_cfg';
      window[c] = window[c] || {};
      (window[c]['fns'] = window[c]['fns']||[]).push(cb);
    } else {
      cb();
    }
  }

  // Usage
  grecaptcha.ready(function(){
    grecaptcha.render("container", {
      sitekey: "ABC-123"
    });
  });
</script>
1
0

I know this is an old question but maybe this will help someone. The reason I was getting this 'Uncaught ReferenceError: grecaptcha is not defined' error was because I couldn't reach the dependency js file (recaptcha_en.js) which is hosted on www.gstatic.com. Once I solved that issue, it worked for me.

2
  • link isn't valid
    – stanimirsp
    Nov 11, 2020 at 15:47
  • 2
    It wasn't meant as a link, it was meant as a hostname. This server was blocked by my network policy which is what caused the issue for me.
    – Freddie
    Nov 11, 2020 at 17:12
0

I have solved the problem by updating site key and secret key. Actually I was using v3 API but used v2 configuration.

After using v3 key, my captcha is working fine.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.