abinnovision / vue-recaptcha-v3

A simple and easy to use reCAPTCHA (v3 only) library for Vue.
Apache License 2.0
241 stars 26 forks source link

Cannot use recaptcha on a specific component #460

Open cod3rshotout opened 3 years ago

cod3rshotout commented 3 years ago

I would like to implement recaptcha only to login and register component, so I wrote the following code:

<script lang="ts">
import { defineComponent, reactive, ref } from "vue";
import { useRouter } from "vue-router";
import { Credentials, ApiError } from "../types/api";
import Vue from "vue";
import { VueReCaptcha } from "vue-recaptcha-v3";

export default defineComponent({
name: "Register",
components: {
    VueReCaptcha,
},
mounted() {
    VueReCaptcha(Vue, { siteKey: "CAPTCHA_SITE_KEY" });
},
setup() {
    const initialState: Credentials = {
    username: "",
    email: "",
    password: "",
    password2: "",
    };

    const data = reactive<Credentials>({ ...initialState });
    const validate = reactive<Credentials>({ ...initialState });

    const alertMessage = ref("");

    const router = useRouter();

    const submit = async () => {
    Object.assign(validate, initialState);
    alertMessage.value = "";

    const res = await fetch(`api/auth/register`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(data),
    });

    if (!res.ok) {
        const response = await res.json();

        // lista di errori
        if (response.errors) {
        const errors: ApiError[] = response.errors;

        for (const err of errors) {
            validate[err.param] = err.msg;
        }
        } else {
        alertMessage.value = (response as ApiError).msg;
        }
    }

    /*
    if (res.text === 200) {
        await router.push("/login");
    }*/
    };

    return {
    data,
    validate,
    alertMessage,
    //recaptcha,
    submit,
    };
},
});
</script>

the problem is that I get the following error:

could someone tell me what I did wrong?

mssayari commented 2 years ago

Hey @cod3rshotout , Have you found any solution for this problem? I only need it in my register page but when we add it in our main, it appears on all pages!

nekooee commented 1 year ago

Use autoHideBadge in loaderOptions

loaderOptions: {
    autoHideBadge: true
}

Create a wrapper composable to use it.

// use-recaptcha.ts
import { onMounted, onUnmounted } from 'vue';
import {
  IReCaptchaComposition,
  useReCaptcha as _useReCaptcha,
} from 'vue-recaptcha-v3';

export const useReCaptcha = () => {
  const { executeRecaptcha, isLoaded, instance, recaptchaLoaded } =
    _useReCaptcha() as IReCaptchaComposition;

  onMounted(() => {
    instance.value?.showBadge();
  });

  onUnmounted(() => {
    instance.value?.hideBadge();
  });

  return {
    isLoaded,
    executeRecaptcha,
    recaptchaLoaded,
  };
};

This will toggle it when you use it in a page component.

But this only hides the badge and the script is loaded in the background on all pages. I'm using Laravel combined with Vue and I only need the google recaptcha script to be loaded on one of the pages and not on all the pages. It's strange that this component doesn't provide any solution for loading locally, and it's too bad that an extra script is loaded all over the site.

codeflorist commented 2 months ago

checkout this comment for a possible solution: https://github.com/AurityLab/vue-recaptcha-v3/issues/680#issuecomment-2360281430