Basic Usage
The simplest way to use react-google-recaptcha is with the onChange callback, which fires when the user completes the CAPTCHA challenge.
Import the Component
Import ReCAPTCHA into your React component:import ReCAPTCHA from "react-google-recaptcha";
Create the onChange Handler
Define a function to handle the CAPTCHA response token:function onChange(value) {
console.log("Captcha value:", value);
}
The value parameter contains the response token string if successful, or null if the CAPTCHA expired.
Render the Component
Add the ReCAPTCHA component to your form:function App() {
function onChange(value) {
console.log("Captcha value:", value);
}
return (
<div>
<h1>My Form</h1>
<ReCAPTCHA
sitekey="your_site_key_here"
onChange={onChange}
/>
</div>
);
}
Here’s a complete example of a contact form with reCAPTCHA protection:
import { useState } from "react";
import ReCAPTCHA from "react-google-recaptcha";
function ContactForm() {
const [formData, setFormData] = useState({ name: "", email: "", message: "" });
const [captchaToken, setCaptchaToken] = useState(null);
function onCaptchaChange(value) {
console.log("Captcha value:", value);
setCaptchaToken(value);
}
function handleSubmit(e) {
e.preventDefault();
if (!captchaToken) {
alert("Please complete the CAPTCHA");
return;
}
// Send formData and captchaToken to your backend
console.log("Submitting form with CAPTCHA token:", captchaToken);
// fetch('/api/contact', {
// method: 'POST',
// body: JSON.stringify({ ...formData, captchaToken })
// });
}
return (
<form onSubmit={handleSubmit}>
<input
type="text"
placeholder="Name"
value={formData.name}
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
/>
<input
type="email"
placeholder="Email"
value={formData.email}
onChange={(e) => setFormData({ ...formData, email: e.target.value })}
/>
<textarea
placeholder="Message"
value={formData.message}
onChange={(e) => setFormData({ ...formData, message: e.target.value })}
/>
<ReCAPTCHA
sitekey="your_site_key_here"
onChange={onCaptchaChange}
/>
<button type="submit">Submit</button>
</form>
);
}
Using Refs for Programmatic Control
For more control, you can use refs to access the component’s API methods:
import React from "react";
import ReCAPTCHA from "react-google-recaptcha";
class MyForm extends React.Component {
constructor(props) {
super(props);
this.recaptchaRef = React.createRef();
}
onSubmit = () => {
const recaptchaValue = this.recaptchaRef.current.getValue();
if (!recaptchaValue) {
alert("Please complete the CAPTCHA");
return;
}
this.props.onSubmit(recaptchaValue);
};
render() {
return (
<form onSubmit={this.onSubmit}>
<ReCAPTCHA
ref={this.recaptchaRef}
sitekey="your_site_key_here"
onChange={(value) => console.log("Captcha value:", value)}
/>
<button type="submit">Submit</button>
</form>
);
}
}
Available Ref Methods
When using refs, you have access to these methods:
| Method | Description |
|---|
getValue() | Returns the current CAPTCHA response token |
getWidgetId() | Returns the widget ID assigned by reCAPTCHA |
reset() | Resets the CAPTCHA widget |
execute() | Programmatically invokes the challenge (for invisible reCAPTCHA) |
executeAsync() | Returns a Promise that resolves to the token |
Invisible reCAPTCHA
Invisible reCAPTCHA doesn’t show a visible widget. You trigger the challenge programmatically:
import { useRef } from "react";
import ReCAPTCHA from "react-google-recaptcha";
function InvisibleForm() {
const recaptchaRef = useRef();
function onChange(value) {
console.log("Captcha value:", value);
// Submit form with value
}
function onSubmit(e) {
e.preventDefault();
recaptchaRef.current.execute();
}
return (
<form onSubmit={onSubmit}>
<input type="text" placeholder="Name" />
<ReCAPTCHA
ref={recaptchaRef}
size="invisible"
sitekey="your_site_key_here"
onChange={onChange}
/>
<button type="submit">Submit</button>
</form>
);
}
Handling Expiration and Errors
CAPTCHA challenges expire after a period of time. Handle these cases with callbacks:
import { useState, useRef } from "react";
import ReCAPTCHA from "react-google-recaptcha";
function RobustForm() {
const [captchaToken, setCaptchaToken] = useState(null);
const recaptchaRef = useRef();
function onChange(value) {
setCaptchaToken(value);
}
function onExpired() {
console.log("CAPTCHA expired");
setCaptchaToken(null);
alert("CAPTCHA expired. Please verify again.");
}
function onErrored() {
console.log("CAPTCHA error");
setCaptchaToken(null);
alert("CAPTCHA error. Please try again.");
}
function handleSubmit(e) {
e.preventDefault();
if (!captchaToken) {
alert("Please complete the CAPTCHA");
return;
}
// Submit form
console.log("Submitting with token:", captchaToken);
// Reset CAPTCHA after submission
recaptchaRef.current.reset();
setCaptchaToken(null);
}
return (
<form onSubmit={handleSubmit}>
<input type="text" placeholder="Your input" />
<ReCAPTCHA
ref={recaptchaRef}
sitekey="your_site_key_here"
onChange={onChange}
onExpired={onExpired}
onErrored={onErrored}
/>
<button type="submit" disabled={!captchaToken}>
Submit
</button>
</form>
);
}
Backend Verification
Important: Always verify the CAPTCHA token on your backend server. Frontend validation alone is not secure.
After receiving the token from your frontend, verify it on your server:
Backend Example (Node.js)
const axios = require('axios');
async function verifyCaptcha(token) {
const secretKey = process.env.RECAPTCHA_SECRET_KEY;
const response = await axios.post(
'https://www.google.com/recaptcha/api/siteverify',
null,
{
params: {
secret: secretKey,
response: token,
},
}
);
return response.data.success;
}
// In your API endpoint:
app.post('/api/submit', async (req, res) => {
const { captchaToken } = req.body;
const isValid = await verifyCaptcha(captchaToken);
if (!isValid) {
return res.status(400).json({ error: 'CAPTCHA verification failed' });
}
// Process form submission
res.json({ success: true });
});
Next Steps
Component API
Explore all available props and configuration options
Examples
See more real-world examples and use cases