The ReCAPTCHA component exposes several public methods that can be accessed via a React ref. These methods allow you to programmatically interact with the reCAPTCHA widget.
Accessing Methods via Ref
To use these methods, you need to create a ref and attach it to the component:
import React, { useRef } from "react";
import ReCAPTCHA from "react-google-recaptcha";
function MyForm() {
const recaptchaRef = useRef();
const handleSubmit = () => {
const token = recaptchaRef.current.getValue();
console.log("Token:", token);
};
return (
<form onSubmit={handleSubmit}>
<ReCAPTCHA
ref={recaptchaRef}
sitekey="your-site-key"
/>
<button type="submit">Submit</button>
</form>
);
}
Methods
getValue()
Returns the current response token from the reCAPTCHA widget.
Signature:
getValue(): string | null
Returns:
string - The captcha response token if the user has completed the challenge
null - If the challenge hasn’t been completed or has expired
Example:
const recaptchaRef = React.createRef();
const handleSubmit = (event) => {
event.preventDefault();
const token = recaptchaRef.current.getValue();
if (!token) {
alert("Please complete the captcha");
return;
}
// Send token to backend for verification
fetch("/api/verify", {
method: "POST",
body: JSON.stringify({ token }),
headers: { "Content-Type": "application/json" }
});
};
<form onSubmit={handleSubmit}>
<ReCAPTCHA
ref={recaptchaRef}
sitekey="your-site-key"
/>
<button type="submit">Submit</button>
</form>
Returns the widget ID assigned by the reCAPTCHA API. This is useful for advanced integrations or debugging.
Signature:
getWidgetId(): number | null
Returns:
number - The widget ID assigned by Google’s reCAPTCHA
null - If the widget hasn’t been initialized yet
Example:
const recaptchaRef = React.createRef();
const logWidgetInfo = () => {
const widgetId = recaptchaRef.current.getWidgetId();
console.log("Widget ID:", widgetId);
};
<>
<ReCAPTCHA
ref={recaptchaRef}
sitekey="your-site-key"
/>
<button onClick={logWidgetInfo}>Get Widget ID</button>
</>
reset()
Resets the reCAPTCHA widget, clearing any user input and allowing them to complete the challenge again.
Signature:
Returns: void
Example:
const recaptchaRef = React.createRef();
const handleError = (error) => {
console.error("Submission failed:", error);
// Reset captcha so user can try again
recaptchaRef.current.reset();
};
const handleSubmit = async (event) => {
event.preventDefault();
const token = recaptchaRef.current.getValue();
try {
await fetch("/api/submit", {
method: "POST",
body: JSON.stringify({ token })
});
} catch (error) {
handleError(error);
}
};
<form onSubmit={handleSubmit}>
<ReCAPTCHA
ref={recaptchaRef}
sitekey="your-site-key"
/>
<button type="submit">Submit</button>
</form>
execute()
Programmatically invokes the reCAPTCHA challenge. This is required when using invisible reCAPTCHA (size="invisible").
Signature:
Returns: void
This method must be called for invisible reCAPTCHA. The onChange callback will be triggered with the token once the challenge is completed.
Example:
import React from "react";
import ReCAPTCHA from "react-google-recaptcha";
function InvisibleRecaptchaForm() {
const recaptchaRef = React.createRef();
const handleSubmit = (event) => {
event.preventDefault();
// Trigger invisible captcha
recaptchaRef.current.execute();
};
const handleChange = (token) => {
console.log("Captcha token:", token);
// Submit form with token
submitForm(token);
};
return (
<form onSubmit={handleSubmit}>
<input type="text" name="email" />
<ReCAPTCHA
ref={recaptchaRef}
size="invisible"
sitekey="your-site-key"
onChange={handleChange}
/>
<button type="submit">Submit</button>
</form>
);
}
executeAsync()
Programmatically invokes the reCAPTCHA challenge and returns a Promise that resolves with the token. This provides a more modern, async/await friendly alternative to using execute() with the onChange callback.
Signature:
executeAsync(): Promise<string>
Returns: Promise<string> - Resolves with the captcha token, or rejects if an error occurs
Example:
import React from "react";
import ReCAPTCHA from "react-google-recaptcha";
function AsyncRecaptchaForm() {
const recaptchaRef = React.useRef();
const handleSubmit = async (event) => {
event.preventDefault();
try {
// Execute captcha and wait for token
const token = await recaptchaRef.current.executeAsync();
// Submit form with token
const response = await fetch("/api/submit", {
method: "POST",
body: JSON.stringify({ token }),
headers: { "Content-Type": "application/json" }
});
if (response.ok) {
console.log("Form submitted successfully");
}
} catch (error) {
console.error("Captcha or submission failed:", error);
} finally {
// Reset for next submission
recaptchaRef.current.reset();
}
};
return (
<form onSubmit={handleSubmit}>
<input type="email" name="email" required />
<ReCAPTCHA
ref={recaptchaRef}
size="invisible"
sitekey="your-site-key"
/>
<button type="submit">Submit</button>
</form>
);
}
forceReset()
Forces a reset of the reCAPTCHA widget without requiring a widget ID. This is useful in edge cases where the widget might not be properly initialized.
Signature:
Returns: void
This method bypasses the normal reset flow and should be used sparingly. In most cases, reset() is preferred.
Example:
const recaptchaRef = React.createRef();
const handleCriticalError = () => {
// Force reset in case of critical error
recaptchaRef.current.forceReset();
};
<ReCAPTCHA
ref={recaptchaRef}
sitekey="your-site-key"
/>
Complete Examples
import React, { useState, useRef } from "react";
import ReCAPTCHA from "react-google-recaptcha";
function ContactForm() {
const recaptchaRef = useRef();
const [error, setError] = useState("");
const handleSubmit = async (event) => {
event.preventDefault();
setError("");
// Get captcha token
const token = recaptchaRef.current.getValue();
if (!token) {
setError("Please complete the reCAPTCHA");
return;
}
try {
const response = await fetch("/api/contact", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
token,
name: event.target.name.value,
email: event.target.email.value,
message: event.target.message.value
})
});
if (response.ok) {
alert("Message sent successfully!");
event.target.reset();
recaptchaRef.current.reset();
} else {
throw new Error("Submission failed");
}
} catch (err) {
setError("Failed to send message. Please try again.");
recaptchaRef.current.reset();
}
};
return (
<form onSubmit={handleSubmit}>
<input type="text" name="name" required />
<input type="email" name="email" required />
<textarea name="message" required />
<ReCAPTCHA
ref={recaptchaRef}
sitekey="your-site-key"
onChange={() => setError("")}
/>
{error && <div className="error">{error}</div>}
<button type="submit">Send Message</button>
</form>
);
}
Invisible reCAPTCHA with executeAsync
import React, { useRef, useState } from "react";
import ReCAPTCHA from "react-google-recaptcha";
function InvisibleForm() {
const recaptchaRef = useRef();
const [isSubmitting, setIsSubmitting] = useState(false);
const handleSubmit = async (event) => {
event.preventDefault();
setIsSubmitting(true);
try {
// Execute invisible captcha and get token
const token = await recaptchaRef.current.executeAsync();
// Submit with token
await fetch("/api/submit", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ token })
});
alert("Success!");
} catch (error) {
alert("Error: " + error.message);
} finally {
setIsSubmitting(false);
recaptchaRef.current.reset();
}
};
return (
<form onSubmit={handleSubmit}>
<input type="email" name="email" required />
<ReCAPTCHA
ref={recaptchaRef}
sitekey="your-site-key"
size="invisible"
/>
<button type="submit" disabled={isSubmitting}>
{isSubmitting ? "Submitting..." : "Submit"}
</button>
</form>
);
}
Class Component Usage
If you’re using class components, you can still access methods via refs:
import React from "react";
import ReCAPTCHA from "react-google-recaptcha";
class MyForm extends React.Component {
constructor(props) {
super(props);
this.recaptchaRef = React.createRef();
}
handleSubmit = (event) => {
event.preventDefault();
const token = this.recaptchaRef.current.getValue();
if (token) {
this.props.onSubmit(token);
}
};
handleError = () => {
this.recaptchaRef.current.reset();
};
render() {
return (
<form onSubmit={this.handleSubmit}>
<ReCAPTCHA
ref={this.recaptchaRef}
sitekey="your-site-key"
/>
<button type="submit">Submit</button>
</form>
);
}
}