48

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

42

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> 
Sign up to request clarification or add additional context in comments.

11 Comments

but i want to render the captcha challenge not on pageload. i want to render it after user enters into some bootstrap modal
@nodeofcode It is not page onload. This is provided by recaptcha. I have updated my answer with the example
i do get your point.. but how can i render captcha into block which doesn't exists
I didn't get what you meant by but how can i render captcha into block which doesn't exists ?
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.
|
7

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> 

Comments

5

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. :)

Comments

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>

Comments

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> 

Comments

2

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> 

3 Comments

Not sure why but I couldn't get this working for v3. google.com/recaptcha/api.js?onload=loadReCaptcha&render={key} seemed to work
I saw this example on their documentation page too, and I wondered how it could possibly work. I wonder if maybe it was supposed to be if (grecaptcha.render === undefined) in the grecaptcha.ready function.
what would a promise based version of this look like?
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>

Comments

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 Comments

link isn't valid
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.
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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.