Stop spam without punishing real users. This guide shows how to add Google reCAPTCHA to any website—particularly contact/enquiry forms—using clear, production‑ready patterns for v2 Checkbox, v2 Invisible, and v3 (score‑based).
✍️ Short Summary
-
Register your site at Google reCAPTCHA Admin to get site key and secret key.
-
Add the client script and the widget/token on your form.
-
Verify on server (never in the browser) before processing or sending email.
-
Fail gracefully, log attempts, and rate‑limit.
📚 What is reCAPTCHA?
Google reCAPTCHA helps differentiate humans from bots. It comes in multiple modes:
Version | UX | How it works | Best for |
---|---|---|---|
v2 Checkbox | User ticks "I'm not a robot"; may get challenge | Risk analysis + optional image/puzzle challenges | Classic forms where an extra click is OK |
v2 Invisible | No visible checkbox; challenge only if risky | Auto‑fires on submit | Forms where you want fewer UI elements |
v3 (Score) | Completely invisible; returns a score (0.0–1.0) | You decide allow/deny or apply friction | High‑traffic sites; fine‑tuned rules & analytics |
Tip: For first‑time implementations, start with v2 Checkbox (most predictable). Scale to v3 later for better UX and analytics.
✅ Prerequisites
-
A public website domain (works on localhost for testing).
-
Ability to edit your HTML and server code (PHP/Node/Python etc.).
-
A place to keep secrets (ENV vars; never hardcode in JS).
1) 🔑 Register your site and get keys
-
Open the reCAPTCHA Admin Console (Google account required).
-
Click Create / +.
-
Choose your type: reCAPTCHA v2 (Checkbox or Invisible) or reCAPTCHA v3.
-
Add one or more Domains (e.g.,
example.com
) and save. -
Copy your Site key (public) and Secret key (server‑side only).
Multiple environments: create separate keys for dev/stage/prod to keep analytics clean.
2) 💻 Front‑end integration
A) reCAPTCHA v2 Checkbox (recommended starter)
Add the script and widget to your form:
<!-- Include once per page -->
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
<form id="contactForm" method="POST" action="/contact">
<input type="text" name="name" placeholder="Your Name" required>
<input type="email" name="email" placeholder="Your Email" required>
<textarea name="message" placeholder="Your Message" required></textarea>
<!-- The reCAPTCHA widget -->
<div class="g-recaptcha" data-sitekey="YOUR_SITE_KEY"></div>
<button type="submit">Send</button>
</form>
On submit, Google adds a hidden input named g-recaptcha-response
to your form. You must verify it server‑side.
B) reCAPTCHA v2 Invisible
Attach reCAPTCHA to your submit button; the challenge appears only when needed.
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
<form id="contactForm" method="POST" action="/contact">
<!-- your fields -->
<button
class="g-recaptcha"
data-sitekey="YOUR_SITE_KEY"
data-callback="onSubmit"
data-size="invisible"
type="submit">
Send
</button>
</form>
<script>
function onSubmit() {
document.getElementById('contactForm').submit();
}
</script>
C) reCAPTCHA v3 (score‑based, no widget)
Add the v3 script and request a token at submit. Send that token with your form to the server.
<script src="https://www.google.com/recaptcha/api.js?render=YOUR_SITE_KEY"></script>
<form id="contactForm" method="POST" action="/contact">
<!-- your fields -->
<input type="hidden" name="recaptcha_token" id="recaptcha_token">
<button type="submit">Send</button>
</form>
<script>
grecaptcha.ready(function () {
const form = document.getElementById('contactForm');
form.addEventListener('submit', function (e) {
e.preventDefault();
grecaptcha.execute('YOUR_SITE_KEY', { action: 'contact' }).then(function (token) {
document.getElementById('recaptcha_token').value = token;
form.submit();
});
});
});
</script>
Assign meaningful
action
names likelogin
,contact
,checkout
to analyze traffic and set per‑action thresholds.
3) 🛡️ Server‑side verification (MUST‑DO)
Always verify tokens on the server using your secret key.
PHP (cURL)
<?php
function verify_recaptcha_v2($token, $secret) {
$ch = curl_init('https://www.google.com/recaptcha/api/siteverify');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => [
'secret' => $secret,
'response' => $token,
'remoteip' => $_SERVER['REMOTE_ADDR'] ?? null,
],
CURLOPT_TIMEOUT => 5,
]);
$out = curl_exec($ch);
if ($out === false) return [ 'success' => false, 'error-codes' => ['curl_error'] ];
$json = json_decode($out, true);
return $json ?: [ 'suc