The `react-google-recaptcha` library provides a simple and declarative way to integrate Google reCAPTCHA into React applications. Google reCAPTCHA is a free service that helps protect websites from spam and abuse by differentiating between human and automated access. It offers various types, including 'I'm not a robot' checkbox, invisible reCAPTCHA, and reCAPTCHA v3 (score-based).
Purpose and Functionality:
* Bot Prevention: The primary goal is to prevent bots, spammers, and malicious automated scripts from interacting with your website, such as submitting forms, creating accounts, or posting comments.
* User Experience: For users, it aims to be as unobtrusive as possible, often requiring just a single click or even running entirely in the background.
* Client-Side Integration: `react-google-recaptcha` handles the rendering of the reCAPTCHA widget on the client side, managing its lifecycle and user interactions.
* Token Generation: Upon successful user verification (or background assessment for v3), reCAPTCHA generates a unique token. This token is crucial for server-side verification.
Key Features and Props:
* `sitekey` (required): Your reCAPTCHA site key obtained from the Google reCAPTCHA admin console. This key is client-side public.
* `onChange(token)`: A callback function that is triggered when the user successfully completes the reCAPTCHA challenge or when the invisible reCAPTCHA generates a token. It receives the reCAPTCHA token as an argument.
* `onExpired()`: A callback function invoked when the reCAPTCHA token expires (typically after 2 minutes). You should re-render or re-verify if this happens.
* `onError(error)`: A callback function for any errors during reCAPTCHA loading or execution.
* `theme`: 'light' or 'dark' (for checkbox reCAPTCHA).
* `size`: 'normal', 'compact', or 'invisible' (for checkbox reCAPTCHA).
* `hl`: Specifies the language code (e.g., 'en', 'es', 'fr') to display the reCAPTCHA widget in a specific language.
Server-Side Verification (Crucial Step):
While `react-google-recaptcha` handles the client-side rendering and token generation, it is absolutely essential to verify this token on your server-side application. Without server-side verification, an attacker could bypass the client-side reCAPTCHA by simply submitting form data without a valid token. The server-side verification involves sending the received token along with your secret key (obtained from the Google reCAPTCHA admin console) to Google's reCAPTCHA verification API. Google then responds with a success status and other details, confirming the legitimacy of the token.
Example Code
import React, { useState } from 'react';
import ReCAPTCHA from 'react-google-recaptcha';
const MyFormWithRecaptcha = () => {
const [recaptchaToken, setRecaptchaToken] = useState(null);
const [formData, setFormData] = useState({
name: '',
email: '',
message: '',
});
// Replace with your actual reCAPTCHA site key from Google Admin Console
// For security, use environment variables in a real application (e.g., .env file)
const RECAPTCHA_SITE_KEY = process.env.REACT_APP_RECAPTCHA_SITE_KEY || 'YOUR_RECAPTCHA_SITE_KEY';
const handleRecaptchaChange = (token) => {
console.log('reCAPTCHA Token:', token);
setRecaptchaToken(token);
};
const handleFormChange = (e) => {
const { name, value } = e.target;
setFormData(prevData => ({ ...prevData, [name]: value }));
};
const handleSubmit = async (e) => {
e.preventDefault();
if (!recaptchaToken) {
alert('Please complete the reCAPTCHA challenge.');
return;
}
// In a real application, you would send formData and recaptchaToken to your backend server
// for further processing and server-side reCAPTCHA verification.
try {
const response = await fetch('/api/submit-form', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
...formData,
recaptchaToken: recaptchaToken,
}),
});
const result = await response.json();
if (result.success) {
alert('Form submitted successfully! Server-side reCAPTCHA verification passed.');
// Reset form and reCAPTCHA (if needed, reCAPTCHA often resets on token expiry or successful submission)
setFormData({ name: '', email: '', message: '' });
setRecaptchaToken(null);
} else {
alert(`Form submission failed: ${result.message || 'Server verification failed.'}`);
}
} catch (error) {
console.error('Error submitting form:', error);
alert('An error occurred during form submission.');
}
};
return (
<form onSubmit={handleSubmit} style={{ padding: '20px', maxWidth: '500px', margin: 'auto', border: '1px solid #ccc', borderRadius: '8px', boxShadow: '0 2px 4px rgba(0,0,0,0.1)' }}>
<h2>Contact Us</h2>
<div style={{ marginBottom: '15px' }}>
<label htmlFor="name" style={{ display: 'block', marginBottom: '5px', fontWeight: 'bold' }}>Name:</label>
<input
type="text"
id="name"
name="name"
value={formData.name}
onChange={handleFormChange}
required
style={{ width: '100%', padding: '10px', boxSizing: 'border-box', border: '1px solid #ddd', borderRadius: '4px' }}
/>
</div>
<div style={{ marginBottom: '15px' }}>
<label htmlFor="email" style={{ display: 'block', marginBottom: '5px', fontWeight: 'bold' }}>Email:</label>
<input
type="email"
id="email"
name="email"
value={formData.email}
onChange={handleFormChange}
required
style={{ width: '100%', padding: '10px', boxSizing: 'border-box', border: '1px solid #ddd', borderRadius: '4px' }}
/>
</div>
<div style={{ marginBottom: '15px' }}>
<label htmlFor="message" style={{ display: 'block', marginBottom: '5px', fontWeight: 'bold' }}>Message:</label>
<textarea
id="message"
name="message"
value={formData.message}
onChange={handleFormChange}
required
rows="5"
style={{ width: '100%', padding: '10px', boxSizing: 'border-box', border: '1px solid #ddd', borderRadius: '4px' }}
></textarea>
</div>
<div style={{ marginBottom: '20px' }}>
<ReCAPTCHA
sitekey={RECAPTCHA_SITE_KEY}
onChange={handleRecaptchaChange}
onExpired={() => setRecaptchaToken(null)} // Clear token if expired
onError={() => alert('reCAPTCHA encountered an error. Please try again.')}
// You can add theme="dark" or size="compact" here if desired for checkbox reCAPTCHA
/>
</div>
<button
type="submit"
disabled={!recaptchaToken}
style={{
padding: '10px 20px',
backgroundColor: recaptchaToken ? '#007bff' : '#cccccc',
color: 'white',
border: 'none',
borderRadius: '5px',
cursor: recaptchaToken ? 'pointer' : 'not-allowed',
fontSize: '16px',
fontWeight: 'bold'
}}
>
Submit
</button>
</form>
);
};
export default MyFormWithRecaptcha;








react-google-recaptcha