Как можно динамически интегрировать Google reCaptcha v3 в проект на Nuxt 3?

Добрый день! <br/> Я пытаюсь интегрировать Google reCaptcha v3 в проект на Nuxt 3. <br/> Настроить её на всем сайте, как описано в <a href="https://practicaldev-herokuapp-com.global.ssl.fastly.net/fitrakun/integrating-nuxt-3-with-recaptcha-v3-for-token-handling-2dp0" rel="nofollow">гайде</a>, не вызывает проблем. <br/> Однако стоит отметить, что в этом руководстве пропущена информация о необходимости отображения иконки, что может нарушать политику Google и права человека, возможно, приведя к блокировке использования рекапчи. <br/> <br/> Мне не хотелось бы, чтобы иконка появлялась на каждой странице, и сбор данных скриптом также вызывает некоторые опасения. <br/> Поэтому логичным решением будет подключать рекаптчу только в тех местах, где она необходима. <br/> Я разработал композабл с методами initReCaptcha и executeRecaptcha. <br/> Это позволяет подключать каптчу только на страницах, где вызывается метод initReCaptcha(), при этом она появляется только там, где требуется. <br/> <br/> Тем не менее, возникла проблема. <br/> <br/> При переходе на другую страницу с помощью navigateTo(), если рекаптчи не было, она появляется, но <b>если она уже загружена, то при переходе на любую другую страницу она не исчезает.</b> <br/> Я пытался полностью удалить данные о рекаптче перед переходом, но в таком случае она переставала работать при последующих переходах через navigateTo(). <br/> В моем композабле есть следующий код: <br/> <pre><code class="javascript">import {VueReCaptcha} from 'vue-recaptcha-v3';
import {useReCaptcha} from 'vue-recaptcha-v3';

export const useGoogleReCaptcha = () =&gt; {
    const recaptchaInstance = ref(null);
    const nuxtApp = useNuxtApp();
    const runtimeConfig = useRuntimeConfig();
    const initReCaptcha = () =&gt; {
        if (proc
  • 20 марта 2025 г. 12:34
Ответы на вопрос 2
Чтобы динамически интегрировать Google reCaptcha v3 в проект на Nuxt 3, важно правильно управлять инициализацией и очищением экземпляра reCaptcha при переходах между страницами. Это позволит избежать проблем с отображением иконки, когда она не требуется.

Вот пример того, как можно организовать ваш композабл для динамической интеграции reCaptcha v3:

### Шаг 1: Установка зависимостей

Если вы еще не установили зависимости, выполните их установку:

```bash
npm install vue-recaptcha-v3
```

### Шаг 2: Создание композабла

Создайте файл `useGoogleReCaptcha.js` в папке `composables` вашего проекта:

```javascript
import { ref } from 'vue';
import { useReCaptcha } from 'vue-recaptcha-v3';

export const useGoogleReCaptcha = () => {
    const recaptchaInstance = ref(null);
    const { executeRecaptcha, setKey, getKey } = useReCaptcha();

    const initReCaptcha = () => {
        if (!recaptchaInstance.value) {
            recaptchaInstance.value = true;
            setKey('<YOUR_RECAPTCHA_SITE_KEY>');
            // optionally load reCaptcha script
        }
    };

    const clearReCaptcha = () => {
        if (recaptchaInstance.value) {
            recaptchaInstance.value = null;
            // optional cleanup if needed
        }
    };

    return {
        initReCaptcha,
        clearReCaptcha,
        executeRecaptcha,
    };
};
```

### Шаг 3: Использование в компонентах

Теперь в любом компоненте, где вам нужно использовать reCaptcha, вы можете сделать следующее:

```vue
<template>
  <div>
    <button @click="onSubmit">Отправить</button>
  </div>
</template>

<script setup>
import { onMounted, onBeforeUnmount } from 'vue';
import { useGoogleReCaptcha } from '@/composables/useGoogleReCaptcha';

const { initReCaptcha, clearReCaptcha, executeRecaptcha } = useGoogleReCaptcha();

const onSubmit = async () => {
    // Выполняем reCaptcha, если необходимо
    const token = await executeRecaptcha('form_submit');
    console.log(token); // Отправьте токен на сервер для проверки
}

onMounted(() => {
    initReCaptcha();
});

onBeforeUnmount(() => {
    clearReCaptcha();
});
</script>
```

### Шаг 4: Управление состоянием

Убедитесь, что `initReCaptcha` вызывается только тогда, когда рекапча необходима, а `clearReCaptcha` вызывается перед уничтожением компонента. Это гарантирует, что рекапча загружается только на страницах, где это требуется, и правильно очищается при переходе на другую страницу.

### Дополнительные поправки

Если проблема сохраняется, и иконка каптчи не исчезает по вашему шаблону, вы можете еще добавить проверку, чтобы реализовать логику показа и скрытия в зависимости от состояния вашего приложения:

```javascript
const isReCaptchaNeeded = ref(false);

const initReCaptcha = () => {
    if (isReCaptchaNeeded.value) return;
    // ... остальная инициализация
};

const onNavigate = () => {
    isReCaptchaNeeded.value = false; // Сбросить флаг перед переходом
    clearReCaptcha();
};

// Обязательно вызывайте onNavigate до перехода по ссылке
```

Таким образом, вы можете точно контролировать, когда и иконка рекапчи будет показана или скрыта, предотвращая ненужные запросы к API и соблюдая политику Google.
Как вариант, переделать код библиотеки под нужный композабл, тогда не нужно будет на глобальный объект Vue цеплять инстанс рекапчи
Похожие вопросы