- I have been trying to get Google ReCAPTCHA v2 invisible work with sveltekit 2 / svelte 5 and I have run into a few issues
- First of all this is the documentation for how to load CAPTCHA in your javascript code
- And here is a section on how to actually go about using it to display an INVISIBLE v2 CAPTCHA
- I have tried all the LLMs (Claude, ChatGPT, Gemini, Deepseek, Grok) and got only half baked answers from all of them before asking this question
- I have 4 forms, a login, signup, fot and reset form and I want to use the same ReCAPTCHA everywhere.
- So I created a component that needs to have 2 functions as follows
GoogleReCAPTCHA.svelte
async function init() {
...
}
export async function getToken() {
try {
await init()
...
}
catch (e) {
...
}
}
## Problem 1
- Let us talk about the second function first
- ReCAPTCHA wants you to add 3 callback functions to your window object
<script lang="ts">
...
function onDataCallback(token: string) {
console.log('I got the token here but how do I send it to the calling component', token)
}
function onErrorCallback() {
console.log('something went wrong with ReCAPTCHA')
}
function onExpiredCallback() {
console.log('your ReCAPTCHA expired');
}
onMount(() => {
window.onDataCallback = onDataCallback
window.onErrorCallback = onErrorCallback
window.onExpiredCallback = onExpiredCallback
})
...
</script>
<div class="g-recaptcha"
data-sitekey="_your_site_key_"
data-callback="onDataCallback"
data-error-callback="onErrorCallback"
data-expired-callback="onExpiredCallback"
data-size="invisible">
</div>
- How do I promisify this to return a token to the caller?
- If the functions are not defined on window , they are simply not called
- If the functions are defined inside a function, they are again not called
- The snippet below doesn't work
<script lang="ts'>
export async function getToken() {
return new Promise((resolve, reject) => {
function onDataCallback(token: string) {
resove(token)
}
function onErrorCallback() {
reject(throw new Error('Something went wrong with RECAPTCHA'))
}
function onExpiredCallback() {
reject(throw new Error('RECAPTCHA expired'))
}
window.onDataCallback = onDataCallback
window.onErrorCallback = onErrorCallback
window.onExpiredCallback = onExpiredCallback
})
}
</script>
<div class="g-recaptcha"
data-sitekey="_your_site_key_"
data-callback="onDataCallback"
data-error-callback="onErrorCallback"
data-expired-callback="onExpiredCallback"
data-size="invisible">
</div>
Problem 2
- How to promisify this so that the promise awaits till recaptha loads
Question
- Basically a single function like getToken() should be able to wait for recaptcha to load, return a promise with the token if succesful and an error if something went wrong. I can't seem to make this work using promises