{"id":15184,"library":"react-google-recaptcha","title":"React Google reCAPTCHA Wrapper","description":"react-google-recaptcha is a React component wrapper for Google reCAPTCHA v2, simplifying its integration into web applications. Currently stable at version 3.1.0, it abstracts away the asynchronous loading of the reCAPTCHA JavaScript API and provides a declarative API for rendering and interacting with reCAPTCHA widgets. The library offers props for customizing widget appearance (theme, size, type), language, and badge positioning, as well as callbacks for success (`onChange`), expiration (`onExpired`), and errors (`onErrored`). It also exposes an instance API via React refs for programmatic actions like `reset()`, `getValue()`, `execute()`, and `executeAsync()`, which are particularly useful for invisible reCAPTCHA implementations. Its primary differentiator is streamlining the often complex reCAPTCHA setup into a standard React component lifecycle, reducing boilerplate and common integration pitfalls.","status":"active","version":"3.1.0","language":"javascript","source_language":"en","source_url":"https://github.com/dozoisch/react-google-recaptcha","tags":["javascript","react","react-component","captcha","recaptcha","google-recaptcha"],"install":[{"cmd":"npm install react-google-recaptcha","lang":"bash","label":"npm"},{"cmd":"yarn add react-google-recaptcha","lang":"bash","label":"yarn"},{"cmd":"pnpm add react-google-recaptcha","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Peer dependency for React applications.","package":"react","optional":false}],"imports":[{"note":"ReCAPTCHA is exported as a default export.","wrong":"import { ReCAPTCHA } from 'react-google-recaptcha';","symbol":"ReCAPTCHA","correct":"import ReCAPTCHA from 'react-google-recaptcha';"},{"note":"The onChange prop expects a function that receives the reCAPTCHA token as its first argument.","symbol":"reCAPTCHA onChange event handler","correct":"function onChange(value) { console.log('Captcha value:', value); }"},{"note":"Access instance methods like getValue(), reset(), or execute() via a React ref to the ReCAPTCHA component.","symbol":"reCAPTCHA ref methods (getValue, reset, execute)","correct":"const recaptchaRef = React.createRef(); recaptchaRef.current.getValue();"}],"quickstart":{"code":"import React from 'react';\nimport ReactDOM from 'react-dom';\nimport ReCAPTCHA from 'react-google-recaptcha';\n\nconst RECAPTCHA_SITE_KEY = process.env.RECAPTCHA_SITE_KEY ?? '6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXwpTqiT'; // Example key\n\nfunction App() {\n  function onChange(value) {\n    console.log('Captcha value:', value);\n    // In a real application, send this 'value' (token) to your backend for verification.\n  }\n\n  function onExpired() {\n    console.log('reCAPTCHA challenge expired.');\n  }\n\n  function onErrored(error) {\n    console.error('reCAPTCHA challenge errored:', error);\n  }\n\n  return (\n    <div>\n      <h1>React Google reCAPTCHA Example</h1>\n      <p>Please complete the reCAPTCHA to proceed.</p>\n      <ReCAPTCHA\n        sitekey={RECAPTCHA_SITE_KEY}\n        onChange={onChange}\n        onExpired={onExpired}\n        onErrored={onErrored}\n        theme=\"light\"\n        size=\"normal\"\n      />\n      <p>Note: This sitekey is for demonstration only. Use your own client site key registered with Google reCAPTCHA.</p>\n    </div>\n  );\n}\n\nReactDOM.render(<App />, document.getElementById('root') || document.createElement('div'));","lang":"javascript","description":"Initializes and renders a visible Google reCAPTCHA v2 widget, logging the token on successful completion, expiration, or error. Requires a `root` element or will create one."},"warnings":[{"fix":"Implement a server-side endpoint to receive the reCAPTCHA token and verify it with `https://www.google.com/recaptcha/api/siteverify` before processing any sensitive user action.","message":"reCAPTCHA tokens obtained from the client-side `onChange` callback MUST be verified on a backend server using Google's reCAPTCHA API. Client-side validation alone is insecure and easily bypassed.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Call `recaptchaRef.current.reset()` in your component's logic after your backend successfully validates the token and completes the user action.","message":"reCAPTCHA tokens are typically one-time use. After a successful submission and backend verification, the reCAPTCHA widget must be manually reset using `recaptchaRef.current.reset()` to allow subsequent submissions.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Ensure you call `recaptchaRef.current.execute()` (typically on a form submission) when using `size=\"invisible\"`. Integrate this with your form's submission handler.","message":"For 'invisible' reCAPTCHA (`size=\"invisible\"`), the challenge will not automatically trigger. You must programmatically invoke it using `recaptchaRef.current.execute()` or `recaptchaRef.current.executeAsync()`.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Set the `isolated={true}` prop on your `ReCAPTCHA` component if there's a possibility of other reCAPTCHA instances on the host page where your component is embedded.","message":"Using multiple `ReCAPTCHA` instances on the same page can lead to conflicts. If embedding the component within a plugin or widget, use the `isolated` prop.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"If reCAPTCHA v3 functionality is required, consider using a library specifically designed for v3 or integrating the v3 API directly.","message":"This library is specifically for Google reCAPTCHA v2. While v2 is still supported, Google has released reCAPTCHA v3 which operates differently (score-based, no user interaction). If you need v3, you will need a different library or custom integration.","severity":"deprecated","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-21T00:00:00.000Z","next_check":"2026-07-20T00:00:00.000Z","problems":[{"fix":"Ensure each `ReCAPTCHA` component renders into a unique DOM location. If embedding, consider using the `isolated` prop set to `true`.","cause":"Attempting to render multiple reCAPTCHA widgets into the same DOM element or having conflicting reCAPTCHA instances without proper isolation.","error":"Error: reCAPTCHA has already been rendered in this element"},{"fix":"Double-check the `sitekey` value against your Google reCAPTCHA admin console and ensure the domain registration matches. Verify your browser console for network errors or CSP warnings, and ensure your CSP allows loading scripts from `www.google.com/recaptcha/api.js`.","cause":"The `sitekey` prop is missing, incorrect, or not registered correctly with Google reCAPTCHA for the current domain. Alternatively, network issues, ad blockers, or Content Security Policy (CSP) restrictions might be preventing the script from loading.","error":"reCAPTCHA widget does not appear, or network errors in console (e.g., 'Failed to load resource')"},{"fix":"Ensure the ref is properly initialized and the component is mounted before accessing `recaptchaRef.current`. For functional components, use `useRef` and ensure the code accessing the ref runs after the component has rendered (e.g., within an `useEffect` or an event handler triggered after mount).","cause":"Attempting to call `recaptchaRef.current.getValue()` or other instance methods before the component is fully mounted and the ref has been assigned.","error":"TypeError: Cannot read properties of null (reading 'getValue')"}],"ecosystem":"npm"}