Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

274
Vistas
How to get recaptcha token in SvelteKit contact form

I'm developing a static website using SvelteKit to get my first approach to svelte. I got almost everything working as intended. Everything but the recaptcha protection on contact form.

I can obtain recaptcha token but I'm losing it the passing it to formData request. My relative code is:

<script lang="ts">
    import * as yup from "yup";
    import {createForm, ErrorMessage} from "svelte-forms-lib";
    ...

    function getCaptcha(){
        grecaptcha.ready(function () {
            grecaptcha.execute('recaptcha-key', { action: 'contactForm' })
                .then(function (token) {

                    console.log(token) // here I get the token
                    return token;
                });
        });
    }

    const  sendMail= (values)=>
    {
        const url = '/sendmail.php';

    const formData = new FormData();
    let token = getCaptcha();
    console.log('token: '+token); // here token is null

    formData.append("token", token);

    fetch(url, {
        method: 'post',
    body: formData,
        })
    .then(function (response) {
        console.debug(response.status)
    })
    .catch(function (e) {
        sendError = true;
    console.debug(e);
        });
    }
</script>

Form submission is working fine except, obviously, for recaptcha token.

Thanks for any idea on how to solve it.

about 4 years ago · Juan Pablo Isaza
3 Respuestas
Responde la pregunta

0

token is null because your getCaptcha function isn't actually returning anything, since you're using callbacks to get the token.

function getCaptcha(){  // <- this function isn't returning anything
    grecaptcha.ready(function () {
        grecaptcha.execute('recaptcha-key', { action: 'contactForm' })
            .then(function (token) {  // <- this function returns, but the value isn't going anywhere
                console.log(token);
                return token;
            });
    });
}

To fix this, you may want to look into using async/await syntax for promises. MDN has a great article if you're interested.

You would probably want to do something like this:

async function getCaptcha(){
    await new Promise((resolve, reject) => {
        // grecaptcha.ready needs a callback so we create a promise to await
        grecaptcha.ready(resolve);
    });
    // grecaptcha.execute returns a promise so we can await it
    const token = await grecaptcha.execute('recaptcha-key', { action: 'contactForm' });
    console.log(token);
    return token;
}

const sendMail = async (values) => {
    const url = '/sendmail.php';

    const formData = new FormData();

    let token = await getCaptcha();
    console.log('token: ' + token);

    formData.append("token", token);

    // you have a few options for converting
    // the Promise.catch()
    // you can use a try {} catch {} block
    // or you can use .catch() on this sendMail function
    try {
        const response = fetch(url, {
            method: 'post',
            body: formData,
        });
        console.debug(response.status);
    } catch (e) {
        sendError = true;
        console.debug(e);
    }
}

Keep in mind that this will make the sendMail function an async function, which means you will have to await calls to it, or use sendMail().then(). I believe it's also possible to call async functions directly in synchronous code and have them run, it's just not guaranteed that the stuff in the function will run before the code that comes after the call.

about 4 years ago · Juan Pablo Isaza Denunciar

0

My final code, for clarification, is slightly different in submit function, and I'm posting it for future reference, just in case.

async function getCaptcha(){
        await new Promise((resolve, reject) => {
            // grecaptcha.ready needs a callback so we create a promise to await
            grecaptcha.ready(resolve);
        });
        // grecaptcha.execute returns a promise so we can await it
        const token = await grecaptcha.execute('site-key', { action: 'contactForm' });
        return token;
    }

    const sendMail = async (values) => {
        const url = '/sendmail.php';

        const formData = new FormData();

        let token = await getCaptcha();

        formData.append("name", values.name);
        formData.append("surname", values.surname);
        formData.append("email", values.email);
        formData.append("phone", values.phone);
        formData.append("message", values.message);
        formData.append("token", token);
        formData.append("action", "contactForm");


        // you have a few options for converting
        // the Promise.catch()
        // you can use a try {} catch {} block
        // or you can use .catch() on this sendMail function
        try {
            let response = await fetch(url, {
                method: 'post',
                body: formData,
            });

            if(response.status == 202){
                sendSuccess = true;
                document.querySelector('form').reset();
            }
            if(response.status == 400){
                sendError = true;
            }
        } catch(err) {
            sendError = true;
        }
    }

about 4 years ago · Juan Pablo Isaza Denunciar

0

Instead of handling this yourself, you can use svelte-recaptcha-v2.

Repository

https://github.com/basaran/svelte-recaptcha-v2

Demo

https://basaran.github.io/svelte-recaptcha-v2/demo

P. S I'm the author of the package.

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda