reCAPTCHA v2 Integration
Implement visible reCAPTCHA v2 "I'm not a robot" checkbox protection for maximum spam prevention.
Overview
reCAPTCHA v2 displays a checkbox that users must click to verify they are human. It may show additional challenges like selecting images if the initial assessment is uncertain.
✨ Key Features
- Visible "I'm not a robot" checkbox
- Optional image challenges for suspicious traffic
- Binary pass/fail result (no scoring)
- Higher security than v3 but more friction
- Better for high-value forms requiring certainty
Setup Process
Get reCAPTCHA v2 API Keys
Visit the Google reCAPTCHA Admin Console and:
- Create a new site
- Select "reCAPTCHA v2" → "I'm not a robot" Checkbox
- Add your domains (including localhost for testing)
- Copy your Site Key and Secret Key
Add reCAPTCHA to Your HTML Form
Add the reCAPTCHA v2 script and checkbox to your form:
<!DOCTYPE html>
<html>
<head>
<!-- Add reCAPTCHA v2 script -->
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
</head>
<body>
<form action="https://connect.kitoform.com/f/YOUR_ENDPOINT" method="POST">
<div>
<label for="name">Full Name</label>
<input type="text" name="name" id="name" required />
</div>
<div>
<label for="email">Email Address</label>
<input type="email" name="email" id="email" required />
</div>
<div>
<label for="message">Message</label>
<textarea name="message" id="message" rows="5" required></textarea>
</div>
<!-- reCAPTCHA v2 checkbox -->
<div class="g-recaptcha" data-sitekey="YOUR_SITE_KEY"></div>
<button type="submit">Send Message</button>
</form>
</body>
</html>React Implementation
For React applications, you can use react-google-recaptcha:
npm install react-google-recaptcha
import { useState, useRef } from 'react';
import ReCAPTCHA from 'react-google-recaptcha';
const ContactForm = () => {
const [recaptchaValue, setRecaptchaValue] = useState(null);
const recaptchaRef = useRef();
const handleSubmit = async (e) => {
e.preventDefault();
if (!recaptchaValue) {
alert('Please complete the reCAPTCHA');
return;
}
const formData = new FormData(e.target);
formData.append('g-recaptcha-response', recaptchaValue);
try {
const response = await fetch('https://connect.kitoform.com/f/YOUR_ENDPOINT', {
method: 'POST',
body: formData
});
if (response.ok) {
alert('Form submitted successfully!');
// Reset form and reCAPTCHA
e.target.reset();
recaptchaRef.current.reset();
setRecaptchaValue(null);
} else {
alert('Submission failed. Please try again.');
}
} catch (error) {
console.error('Submission error:', error);
alert('An error occurred. Please try again.');
}
};
const handleRecaptchaChange = (value) => {
setRecaptchaValue(value);
};
return (
<form onSubmit={handleSubmit}>
<div>
<label htmlFor="name">Full Name</label>
<input type="text" name="name" id="name" required />
</div>
<div>
<label htmlFor="email">Email Address</label>
<input type="email" name="email" id="email" required />
</div>
<div>
<label htmlFor="message">Message</label>
<textarea name="message" id="message" rows="5" required />
</div>
{/* reCAPTCHA v2 component */}
<ReCAPTCHA
ref={recaptchaRef}
sitekey="YOUR_SITE_KEY"
onChange={handleRecaptchaChange}
/>
<button type="submit" disabled={!recaptchaValue}>
Send Message
</button>
</form>
);
};
export default ContactForm;Configure Kitoform Settings
Configure reCAPTCHA v2 in your Kitoform dashboard or via API:
{
"settings": {
"captchaProvider": "recaptcha",
"recaptchaEnabled": true,
"recaptchaVersion": "v2",
"recaptchaSiteKey": "6Lc-your-site-key",
"recaptchaSecretKey": "6Lc-your-secret-key",
"recaptchaExpectedHostname": "yoursite.com",
"securityLevel": "strict"
}
}Customization Options
Theme and Size
Customize the appearance of the reCAPTCHA checkbox:
<!-- Light theme (default) -->
<div class="g-recaptcha"
data-sitekey="YOUR_SITE_KEY"
data-theme="light"
data-size="normal">
</div>
<!-- Dark theme -->
<div class="g-recaptcha"
data-sitekey="YOUR_SITE_KEY"
data-theme="dark"
data-size="normal">
</div>
<!-- Compact size -->
<div class="g-recaptcha"
data-sitekey="YOUR_SITE_KEY"
data-size="compact">
</div>Callback Functions
Handle reCAPTCHA events with callback functions:
<div class="g-recaptcha"
data-sitekey="YOUR_SITE_KEY"
data-callback="onRecaptchaSuccess"
data-expired-callback="onRecaptchaExpired"
data-error-callback="onRecaptchaError">
</div>
<script>
function onRecaptchaSuccess(token) {
console.log('reCAPTCHA completed:', token);
// Enable form submission
document.getElementById('submit-btn').disabled = false;
}
function onRecaptchaExpired() {
console.log('reCAPTCHA expired');
// Disable form submission
document.getElementById('submit-btn').disabled = true;
}
function onRecaptchaError() {
console.log('reCAPTCHA error');
// Handle error state
}
</script>Programmatic Control
Control reCAPTCHA programmatically with the JavaScript API:
<script>
// Render reCAPTCHA explicitly
var recaptchaId = grecaptcha.render('recaptcha-container', {
'sitekey': 'YOUR_SITE_KEY',
'theme': 'light',
'callback': function(token) {
console.log('Token:', token);
}
});
// Get response token
var token = grecaptcha.getResponse(recaptchaId);
// Reset reCAPTCHA
grecaptcha.reset(recaptchaId);
</script>
<!-- Container for programmatic rendering -->
<div id="recaptcha-container"></div>Configuration Options
| Data Attribute | Values | Default | Description |
|---|---|---|---|
| data-sitekey | string | - | Your reCAPTCHA site key (required) |
| data-theme | light, dark | light | Visual theme |
| data-size | normal, compact | normal | Size of the widget |
| data-callback | function name | - | Called when user completes CAPTCHA |
| data-expired-callback | function name | - | Called when CAPTCHA expires |
| data-error-callback | function name | - | Called when CAPTCHA encounters error |
Security Benefits
✅ Advantages
- Very high spam blocking effectiveness
- Clear pass/fail result (no ambiguity)
- Works well for critical forms
- Additional challenges for suspicious users
⚠️ Considerations
- Adds friction to user experience
- May reduce conversion rates
- Accessibility concerns for some users
- Requires user interaction
Best Practices
✅ Do's
- Place the reCAPTCHA near the submit button
- Validate that reCAPTCHA is completed before allowing submission
- Provide clear error messages if validation fails
- Reset reCAPTCHA after form submission
- Use appropriate theme (light/dark) for your design
❌ Don'ts
- Don't hide the reCAPTCHA checkbox
- Don't allow form submission without reCAPTCHA completion
- Don't add multiple reCAPTCHA widgets to the same form
- Don't forget to handle expired tokens
Testing
Test Keys
Use these test keys for development (they will always pass):
Test Site Key:
6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhITest Secret Key:
6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWeNote: Test keys always return a successful response. Use only for development and testing.