Open Mohitkumar6122 opened 1 year ago
Onload only fires once for a SPA, so this is expected behavior. What are you trying to do in onload?
I have token generation logic in onload, diffrent for both pages a and b but the onload is firing only for page a (which is loaded earlier) not for page b (after page a).
Hi @Mohitkumar6122!
Thank you for reaching to us! As @e271828- mentioned, , that's the expected behavior! The onLoad is triggered when the hCaptcha script is loaded. You can find more info here. Right now, we don't have the prop that would be triggered when the new instance of hCaptcha is ready for use.
Please try calling hCaptcha execute method inside the useEffect
instead. Here is the example code with the additional isReady
check:
useEffect(() => {
let timeoutId;
if (captchaRef.current?.isReady()) {
executeCaptcha();
} else {
timeoutId = setTimeout(() => {
executeCaptcha();
}, 500);
}
return () => {
if (timeoutId) {
clearTimeout(timeoutId);
}
};
}, []);
const executeCaptcha = async () => {
try {
const captchaResponse = await captchaRef.current.execute({
async: true
});
const { response: responseToken } = captchaResponse;
console.log('Verified asynchronously: ', responseToken);
setToken(responseToken);
} catch (error) {
console.log(error);
}
};
Please let us know if it works for you.
Best Regards, hCaptcha Dev Team
@zoryana94 Thanks for providing a workaround, but this is the same method as I'm using till now. Just one more doubt if I remove the 'hcaptca-api-script' from the head tag when the page a unmounts.
useEffect(() => {
// MY CUSTOM LOGIC
return () => {
const apiScript = document.getElementById("hcaptcha-api-script-id");
apiScript && document.head.removeChild(apiScript as HTMLUnknownElement);
};
}, []);
But after navigating to page b, ideally it should load a new script and onLoad should work ? But its not working. Any ideas what could be the issue here ?
Hi,
@Mohitkumar6122, we check if the script content is loaded, not if the script element is present that should be the reason
however, what do you mean by "this is the same method as I'm using till now"?
you probably use the executeCaptcha
method, but what about the following part:
useEffect(() => {
let timeoutId;
if (captchaRef.current?.isReady()) {
executeCaptcha();
} else {
timeoutId = setTimeout(() => {
executeCaptcha();
}, 500);
}
return () => {
if (timeoutId) {
clearTimeout(timeoutId);
}
};
}, []);
So, my suggestion is that you call the executeCaptcha as in the example above, not in the onLoad.
If that is still not working for you, could you please send us some details of how you've added hCaptcha into your app? or even maybe some test app
Best Regards, hCaptcha Dev Team
@zoryana94 Thanks for the clarification. AS for the second part, Since I'm calling an API, I cannot use the execute method in the useEffect or else it will trigger unnecessary API call every time component rerenders, As of now I'm using the useEffect for the token generation and storing some variable in the sessionStorage to trigger API call only once, But let me try the method you mentioned, I think it'll work.
Hi,
@Mohitkumar6122, we check if the script content is loaded, not if the script element is present that should be the reason
however, what do you mean by "this is the same method as I'm using till now"? you probably use the
executeCaptcha
method, but what about the following part:useEffect(() => { let timeoutId; if (captchaRef.current?.isReady()) { executeCaptcha(); } else { timeoutId = setTimeout(() => { executeCaptcha(); }, 500); } return () => { if (timeoutId) { clearTimeout(timeoutId); } }; }, []);
So, my suggestion is that you call the executeCaptcha as in the example above, not in the onLoad.
If that is still not working for you, could you please send us some details of how you've added hCaptcha into your app? or even maybe some test app
Best Regards, hCaptcha Dev Team
Also How do you check if the script content is loaded ? Are there any signatures that Hcaptcha leaves on the DOM or window object after I remove the script, Ideally it should remove all the dependencies of Hcaptcha ?
Hi,
@Mohitkumar6122 as far as I remember we're checking for the hcaptcha
in the frame window. However, I'd not recommend trying to go with such the workarounds like deleting it or so.
It should be easier to align the current implementation.
So, the executeCaptcha
I put above is also only for the token generation.
Please make sure to use it with the empty dependencies array, so it's called just once. In this case, it should work similar to the behavior you described as desired originally: with onLoad on mounting.
If you make any non-related API call, please put it into the different useEffect
.
Also, it might be useful if you send some code implementation example, so that we could propose the possible solution.
Best Regards, hCaptcha Dev Team
I have 2 pages a and b. I want to call a secure API and handling the bot request with the help of invisible hcaptcha and verify it on middleware. I am using it on mount of component of page a but when i am navigating to page b and again navigate back to a. onload is not running again. Any ideas what are the scenarios in which onload runs? and how to prevent this ?
Page a -> Page b -> Page a captcha working captcha not generating using onload prop