Standard Integration
The most common way to use react-google-recaptcha is to import the default component, which automatically loads the Google reCAPTCHA script and handles initialization.
import ReCAPTCHA from "react-google-recaptcha";
import ReactDOM from "react-dom";
function onChange(value) {
console.log("Captcha value:", value);
}
ReactDOM.render(
<ReCAPTCHA
sitekey="Your client site key"
onChange={onChange}
/>,
document.body
);
Using the onChange Callback
The onChange callback is triggered when the user successfully completes the captcha. It receives the captcha token as its argument, which you should send to your backend for verification.
function onChange(token) {
console.log("Captcha value:", token);
// Send token to your backend for verification
fetch('/api/verify-captcha', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ token })
});
}
Accessing Component Methods with Refs
You can access the component’s API methods using React refs:
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();
this.props.onSubmit(recaptchaValue);
}
render() {
return (
<form onSubmit={this.onSubmit}>
<ReCAPTCHA
ref={this.recaptchaRef}
sitekey="Your client site key"
onChange={this.onChange}
/>
</form>
)
}
}
Available Methods
getValue() - Returns the current captcha token value
getWidgetId() - Returns the reCAPTCHA widget ID
reset() - Forces a reset of the captcha
execute() - Programmatically invokes the challenge (for invisible reCAPTCHA)
executeAsync() - Promise-based version of execute()
Theme Customization
reCAPTCHA supports light and dark themes. The default is light.
<ReCAPTCHA
sitekey="Your client site key"
onChange={onChange}
theme="light"
/>
<ReCAPTCHA
sitekey="Your client site key"
onChange={onChange}
theme="dark"
/>
Size Options
You can control the size of the reCAPTCHA widget with the size prop.
<ReCAPTCHA
sitekey="Your client site key"
onChange={onChange}
size="normal"
/>
This is the default size - a standard reCAPTCHA widget.<ReCAPTCHA
sitekey="Your client site key"
onChange={onChange}
size="compact"
/>
A smaller version ideal for mobile devices or tight layouts.<ReCAPTCHA
sitekey="Your client site key"
onChange={onChange}
size="invisible"
/>
See the Invisible reCAPTCHA guide for details.
Challenge Type
You can specify whether users solve an image or audio challenge. The default is image.
<ReCAPTCHA
sitekey="Your client site key"
onChange={onChange}
type="audio"
/>
The audio type provides an accessible alternative for users with visual impairments.
Handling Expiration and Errors
reCAPTCHA tokens expire after a certain time. You should handle these cases:
function onExpired() {
console.log("Captcha expired");
// Optionally show a message to the user
}
function onErrored() {
console.log("Captcha error - likely network issues");
// Handle the error gracefully
}
<ReCAPTCHA
sitekey="Your client site key"
onChange={onChange}
onExpired={onExpired}
onErrored={onErrored}
/>
If you don’t provide an onExpired callback, the component will call onChange with null when the token expires.
Tab Index
Control the keyboard navigation order with the tabindex prop:
<ReCAPTCHA
sitekey="Your client site key"
onChange={onChange}
tabindex={0}
/>
The default value is 0.
Complete Example
Here’s a complete form with all common options:
import React from "react";
import ReCAPTCHA from "react-google-recaptcha";
function ContactForm() {
const recaptchaRef = React.useRef();
const [formData, setFormData] = React.useState({ name: "", email: "" });
const handleSubmit = async (e) => {
e.preventDefault();
const token = recaptchaRef.current.getValue();
if (!token) {
alert("Please complete the reCAPTCHA");
return;
}
// Submit form with token
await fetch('/api/contact', {
method: 'POST',
body: JSON.stringify({ ...formData, recaptchaToken: token })
});
// Reset the captcha
recaptchaRef.current.reset();
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
value={formData.name}
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
placeholder="Name"
/>
<input
type="email"
value={formData.email}
onChange={(e) => setFormData({ ...formData, email: e.target.value })}
placeholder="Email"
/>
<ReCAPTCHA
ref={recaptchaRef}
sitekey="Your client site key"
theme="light"
size="normal"
onExpired={() => console.log("Expired")}
onErrored={() => console.log("Error")}
/>
<button type="submit">Submit</button>
</form>
);
}