React Google reCAPTCHA v3 Integration
react-google-recaptcha-v3 is a React library that simplifies the integration of Google reCAPTCHA v3 into web applications. It provides a `GoogleReCaptchaProvider` component to manage the reCAPTCHA script loading and context, along with a `useGoogleReCaptcha` hook and a `withGoogleReCaptcha` HOC for executing reCAPTCHA validation programmatically. The library is currently at version 1.11.0 and maintains an active release cadence with regular updates and fixes. It differentiates itself by offering flexible script injection control via `scriptProps` and explicit support for Google reCAPTCHA Enterprise, requiring specific key types and 'Scoring' integration. This library focuses on an invisible reCAPTCHA experience, providing a score to differentiate human from bot interactions without interrupting the user flow.
Common errors
-
Error: reCAPTCHA has already been loaded on this page
cause This error typically occurs if the reCAPTCHA script is loaded multiple times, either by having more than one `GoogleReCaptchaProvider` or by manually including the reCAPTCHA script alongside the library.fixEnsure there is only one `GoogleReCaptchaProvider` component in your application's React tree and remove any other `<script src="https://www.google.com/recaptcha/api.js..."></script>` tags from your HTML or component lifecycle methods. -
TypeError: Cannot read properties of undefined (reading 'executeRecaptcha')
cause The `executeRecaptcha` function from `useGoogleReCaptcha` is `undefined` if the reCAPTCHA script has not finished loading, or if the hook is called outside the `GoogleReCaptchaProvider`'s context.fixEnsure the component calling `useGoogleReCaptcha` is a descendant of `GoogleReCaptchaProvider`. Always check `if (executeRecaptcha)` before attempting to call it. You might also want to display a loading state until `executeRecaptcha` becomes available. -
reCAPTCHA key is missing or invalid (often indicated by a console warning from Google reCAPTCHA itself)
cause The `reCaptchaKey` prop was not provided to `GoogleReCaptchaProvider` or the provided key is incorrect/malformed.fixObtain a valid reCAPTCHA v3 site key from the Google reCAPTCHA admin console and pass it as the `reCaptchaKey` prop to `GoogleReCaptchaProvider`. Verify that the key is correctly formatted and corresponds to your registered domain.
Warnings
- breaking In v1.7.0, the `nonce`, `async`, and `defer` props directly on `GoogleReCaptchaProvider` were grouped into a single `scriptProps` object. Existing direct usages will no longer function as expected.
- gotcha When integrating Google reCAPTCHA Enterprise, you MUST create new site keys specifically for Enterprise and select 'Scoring' as the integration type. Standard reCAPTCHA v3 keys will not work with the `useEnterprise` prop enabled.
- gotcha Placing multiple `GoogleReCaptchaProvider` instances in your application or placing it low in the component tree can lead to performance issues, unnecessary script reloads, or reCAPTCHA conflicts.
- deprecated The `withGoogleReCaptcha` Higher-Order Component (HOC) is primarily for class components. While still supported, the `useGoogleReCaptcha` hook is the recommended and more idiomatic approach for functional components. The HOC may be considered for removal in future major versions.
Install
-
npm install react-google-recaptcha-v3 -
yarn add react-google-recaptcha-v3 -
pnpm add react-google-recaptcha-v3
Imports
- GoogleReCaptchaProvider
const { GoogleReCaptchaProvider } = require('react-google-recaptcha-v3');import { GoogleReCaptchaProvider } from 'react-google-recaptcha-v3'; - useGoogleReCaptcha
import useGoogleReCaptcha from 'react-google-recaptcha-v3/dist/useGoogleReCaptcha';
import { useGoogleReCaptcha } from 'react-google-recaptcha-v3'; - withGoogleReCaptcha
import WithGoogleReCaptcha from 'react-google-recaptcha-v3/withGoogleReCaptcha';
import { withGoogleReCaptcha } from 'react-google-recaptcha-v3';
Quickstart
import React, { useState, useCallback, useEffect } from 'react';
import { GoogleReCaptchaProvider, useGoogleReCaptcha } from 'react-google-recaptcha-v3';
const RECAPTCHA_SITE_KEY = process.env.NEXT_PUBLIC_RECAPTCHA_SITE_KEY ?? 'YOUR_SITE_KEY';
const RecaptchaForm = () => {
const { executeRecaptcha } = useGoogleReCaptcha();
const [token, setToken] = useState<string | null>(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const handleReCaptchaVerify = useCallback(async () => {
setLoading(true);
setError(null);
if (!executeRecaptcha) {
setError('reCAPTCHA not loaded yet!');
setLoading(false);
return;
}
try {
const result = await executeRecaptcha('form_submission');
setToken(result);
console.log('reCAPTCHA token:', result);
// In a real application, send this token to your backend for verification
} catch (e) {
console.error('reCAPTCHA execution failed:', e);
setError('Failed to get reCAPTCHA token.');
} finally {
setLoading(false);
}
}, [executeRecaptcha]);
useEffect(() => {
// Optionally execute reCAPTCHA on component mount or a specific event
// handleReCaptchaVerify();
}, [handleReCaptchaVerify]);
return (
<div>
<h1>Contact Us</h1>
<form onSubmit={(e) => { e.preventDefault(); handleReCaptchaVerify(); }}>
{/* Your form fields here */}
<p>This form is protected by reCAPTCHA.</p>
<button type="submit" disabled={loading}>
{loading ? 'Verifying...' : 'Submit Form'}
</button>
{token && <p>Token received: {token.substring(0, 15)}...</p>}
{error && <p style={{ color: 'red' }}>Error: {error}</p>}
</form>
</div>
);
};
export default function App() {
if (!RECAPTCHA_SITE_KEY || RECAPTCHA_SITE_KEY === 'YOUR_SITE_KEY') {
console.error('Please provide a reCAPTCHA site key via NEXT_PUBLIC_RECAPTCHA_SITE_KEY environment variable or directly in the code.');
return <div>Error: reCAPTCHA site key is missing.</div>;
}
return (
<GoogleReCaptchaProvider reCaptchaKey={RECAPTCHA_SITE_KEY} scriptProps={{ defer: true, async: true }}>
<RecaptchaForm />
</GoogleReCaptchaProvider>
);
}