Fallback

Implementing an abstract fallback flow with two different reCAPTCHA types (e.g., v3 and v2)

You always need a GoogleReCaptchaProvider. In Vue you can set it up with a component, composable, or plugin:

<template>
  <GoogleReCaptchaProvider type="v3" siteKey="your_site_key">
    <slot />
  </GoogleReCaptchaProvider>
</template>

<script setup>
import { GoogleReCaptchaProvider } from '@google-recaptcha/vue';
</script>

In our component, we want to perform verification by sending the reCAPTCHA token to our backend API.

<script setup>
import { useGoogleReCaptcha } from '@google-recaptcha/vue';

const googleReCaptcha = useGoogleReCaptcha();

const onVerify = async () => {
  if (!googleReCaptcha.executeV3) {
    console.log('Execute recaptcha not available');
    return;
  }

  const token = await googleReCaptcha.executeV3('action');
};
</script>

<template>
  <button @click="onVerify">verify</button>
</template>

After receiving the token, call your backend validation; if it fails, you can trigger another reCAPTCHA version with its own siteKey.

<script setup>
import { ref } from 'vue';
import { GoogleReCaptchaCheckbox, useGoogleReCaptcha } from '@google-recaptcha/vue';

const showFallback = ref(false);
const googleReCaptcha = useGoogleReCaptcha();

const onVerify = async () => {
  if (!googleReCaptcha.executeV3) {
    console.log('Execute recaptcha not available');
    return;
  }

  const token = await googleReCaptcha.executeV3('action');

  try {
    // your request with token
    const response = await fetch('/api/verify', {
      method: 'POST',
      body: JSON.stringify({ token })
    });
    // ...
  } catch {
    showFallback.value = true;
  }
};
</script>

<template>
  <button @click="onVerify">verify</button>
  <GoogleReCaptchaCheckbox
    v-if="showFallback"
    siteKey="your_v2_site_key"
    @change="(token) => console.log(token)"
  />
</template>