2026年11月12日

2026年11月12日

Set Up reCAPTCHA v3 in WordPress: Keys, Contact Form 7, Comments

This article is a localized edition of the Japanese original. Read the Japanese original

reCAPTCHA v3 is Google's bot-detection service. Instead of showing a checkbox or an image puzzle, it returns a score from 0.0 to 1.0 based on how the visitor interacts with the page. A score close to 1.0 means the interaction looks human; close to 0.0 means it looks like a bot. Your site reads that score and decides whether to accept the form submission.

This article walks through the process as of October 2026: creating a key, then adding reCAPTCHA v3 to a WordPress contact form (Contact Form 7) and to the comment form.

How reCAPTCHA v3 works, and what to watch for

  • In the browser, calling grecaptcha.execute() issues a token (a one-time string) that is sent to your server together with the form
  • Your server sends the token to Google's verification API (https://www.google.com/recaptcha/api/siteverify) and gets back the score and the action the token was issued for
  • A token expires after two minutes and can be verified only once. Issue it when the user clicks the submit button, not when the page loads
  • Google suggests starting with a threshold of 0.5. Instead of rejecting low-score submissions outright, you can also send them to an administrator for review

Create a key (as of October 2026)

Google has moved reCAPTCHA key management into Google Cloud projects. According to the Google Cloud documentation (as of October 2026), you can no longer create new "Classic" keys in the old admin console (https://www.google.com/recaptcha/admin), and existing Classic keys are being migrated into Google Cloud projects. To create a new key, use the Google Cloud console.

  1. Sign in to the Google Cloud console and select a project (create one if you don't have one)
  2. Open "Fraud Defense" (the reCAPTCHA management page), go to the "Keys" tab and click "Create key"
  3. Enter a recognizable name in "Display name" and choose "Web" for "Application type"
  4. Click "Add a domain" and add your site's domain (for example, example.com). Subdomains are covered by their parent domain
  5. The score-based type is the default. Click "Create key"

The labels above are from the English console. The key's site key is a public value that gets embedded in the browser.

Get the legacy secret key for WordPress plugins

Most WordPress plugins use the classic verification API (siteverify) and ask you to enter a "secret key". Keys created in Google Cloud also come with a legacy secret key for these plugins.

  1. In "Fraud Defense", on the "Keys" tab, click the key you created
  2. On the "Key details" page, open the "Integration" tab and click "Use legacy key" (or "Integrate with a third-party service or plugin")
  3. Copy the legacy secret key that appears

The secret key belongs on the server only. Never put it anywhere that reaches the browser, such as your theme's JavaScript. Also check whether the plugin supports v2 or v3, and make sure it matches the type of key you created (v3 is score-based).

What happens when you exceed the free tier

The Google Cloud documentation (as of October 2026) says the free tier covers 10,000 assessments per month; beyond that you need billing enabled on the project. If you go over the limit without billing, siteverify returns "success, score 0.9" along with an error message about the exceeded quota. In other words, once you are over the limit, bots get through too. On busy sites, check your usage in the Google Cloud console.

Set it up in Contact Form 7

Contact Form 7 has built-in reCAPTCHA v3 integration. These steps were checked with Contact Form 7 6.2 (related article: How to Set Up reCAPTCHA in Contact Form 7).

  1. In the admin area, go to "Contact" → "Integration"
  2. In the reCAPTCHA box, click "Setup integration"
  3. Enter the "Site Key" and the "Secret Key" (the legacy secret key from the previous step), then click "Save Changes"

Once saved, it works without changing any form tags, and a token is attached automatically when the form is submitted. Here is how it behaves:

  • The reCAPTCHA script is loaded on every page of the site, including pages without a form (page views are also used as signals)
  • If the score is higher than the 0.50 threshold, the submission is accepted; otherwise it is treated as spam
  • You can change the threshold with the wpcf7_recaptcha_threshold filter

Here is an example that changes the threshold. Put it in your theme's functions.php or in your own plugin.

<?php
// Lower Contact Form 7's reCAPTCHA v3 threshold to 0.3 (default is 0.50)
add_filter( 'wpcf7_recaptcha_threshold', function () {
	return 0.3;
} );

A higher threshold stops more bots but also flags more real people as spam. If you hear that legitimate messages aren't getting through, lower the value.

Add it to the comment form yourself

There are plugins that add reCAPTCHA to comments and the login screen, but to show how it works, here is an example that adds it to the comment form by hand. It targets WordPress's standard comment form (the form output by comment_form()).

First, define the keys as constants in wp-config.php (above the "That's all, stop editing!" line).

<?php
define( 'MY_RECAPTCHA_SITE_KEY', 'your-site-key' );
define( 'MY_RECAPTCHA_SECRET', 'your-legacy-secret-key' );

Next, create wp-content/mu-plugins/comment-recaptcha.php and save the following code in it (create the mu-plugins folder if it doesn't exist; files placed there are activated automatically).

<?php
/**
 * Plugin Name: Comment reCAPTCHA v3
 * Description: Check the reCAPTCHA v3 score when a comment is posted
 */

// 1. Load the reCAPTCHA script on single posts and attach a token on submit
add_action( 'wp_enqueue_scripts', function () {
	if ( ! defined( 'MY_RECAPTCHA_SITE_KEY' ) || ! is_singular() || ! comments_open( get_queried_object_id() ) ) {
		return;
	}

	wp_enqueue_script(
		'my-recaptcha',
		'https://www.google.com/recaptcha/api.js?render=' . rawurlencode( MY_RECAPTCHA_SITE_KEY ),
		array(),
		null,
		array( 'in_footer' => true )
	);

	$js = <<<'JS'
(function () {
	var form = document.getElementById('commentform');
	if (!form) { return; }
	form.addEventListener('submit', function (e) {
		if (form.dataset.recaptchaDone) { return; }
		e.preventDefault();
		grecaptcha.ready(function () {
			grecaptcha.execute(myRecaptchaSiteKey, { action: 'comment' }).then(function (token) {
				form.querySelector('input[name="my_recaptcha_token"]').value = token;
				form.dataset.recaptchaDone = '1';
				HTMLFormElement.prototype.submit.call(form);
			});
		});
	});
})();
JS;

	wp_add_inline_script( 'my-recaptcha', 'var myRecaptchaSiteKey = ' . wp_json_encode( MY_RECAPTCHA_SITE_KEY ) . ';', 'before' );
	wp_add_inline_script( 'my-recaptcha', $js );
} );

// 2. Add a hidden field to the comment form to hold the token
add_action( 'comment_form', function () {
	echo '<input type="hidden" name="my_recaptcha_token" value="">';
} );

// 3. Verify the token before the comment is saved
add_action( 'pre_comment_on_post', function () {
	if ( ! defined( 'MY_RECAPTCHA_SECRET' ) ) {
		return;
	}

	$token = isset( $_POST['my_recaptcha_token'] ) ? sanitize_text_field( wp_unslash( $_POST['my_recaptcha_token'] ) ) : '';
	$ok    = false;

	if ( '' !== $token ) {
		$response = wp_remote_post(
			'https://www.google.com/recaptcha/api/siteverify',
			array(
				'timeout' => 10,
				'body'    => array(
					'secret'   => MY_RECAPTCHA_SECRET,
					'response' => $token,
				),
			)
		);

		if ( ! is_wp_error( $response ) && 200 === wp_remote_retrieve_response_code( $response ) ) {
			$data = json_decode( wp_remote_retrieve_body( $response ), true );
			$ok   = ! empty( $data['success'] )
				&& isset( $data['action'], $data['score'] )
				&& 'comment' === $data['action']
				&& (float) $data['score'] >= 0.5;
		}
	}

	if ( ! $ok ) {
		wp_die(
			'Your comment could not be submitted. Please reload the page and try again.',
			'Submission error',
			array(
				'response'  => 403,
				'back_link' => true,
			)
		);
	}
} );

Key points in the code:

  • pre_comment_on_post fires only when a comment is submitted from the site's comment form (wp-comments-post.php). Replies from the admin area are not affected
  • In the standard comment form, the submit button's name is submit, so form.submit() points to the button element instead of the method. That is why the code submits with HTMLFormElement.prototype.submit.call(form)
  • Verification checks not only success but also that action is comment, plus the score. This prevents tokens issued on other pages from being reused
  • If the verification API can't be reached, the submission is rejected as well (the code fails closed)

After installing it, post a comment while logged out (for example, from another browser) and confirm it goes through. Also confirm that submitting with the hidden field empty shows the error screen.

The badge and privacy

When reCAPTCHA v3 is loaded, a reCAPTCHA badge appears in the bottom-right corner of the page. Google's FAQ allows you to hide the badge with CSS only if you show the text "This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply." (with links to the Privacy Policy and Terms of Service) somewhere visitors will see it.

.grecaptcha-badge { visibility: hidden; }

reCAPTCHA sends visitor interaction data to Google. State in your site's privacy policy that you use reCAPTCHA.

Troubleshooting

  • Every submission is treated as spam: check whether the site key and secret key belong to different keys, whether the key is not v3 (score-based), or whether the domain registered on the key differs from your site's domain
  • The server can't reach Google: if a firewall or similar blocks traffic from your server to https://www.google.com, verification fails (Fixing "Could not connect to reCAPTCHA" in WordPress)
  • Submitting from a page left open for a while fails: Contact Form 7 and the code above issue the token on submit. Plugins or code that issue a token only when the page loads will get a timeout-or-duplicate error from the verification API if the form is submitted more than two minutes later
  • You use a Content Security Policy: allow https://www.google.com/recaptcha/ and https://www.gstatic.com/recaptcha/ in script-src, https://www.google.com/recaptcha/ and https://recaptcha.google.com/recaptcha/ in frame-src, and https://www.google.com/recaptcha/ in connect-src

Summary

  • As of October 2026, reCAPTCHA keys are created under "Fraud Defense" in the Google Cloud console. For WordPress plugins, use the legacy secret key from the "Integration" tab on the key details page
  • In Contact Form 7, entering the keys under "Contact" → "Integration" is all it takes to enable v3. Change the threshold with wpcf7_recaptcha_threshold
  • If you build it yourself, issue the token on submit and check success, action and the score on the server
  • If you exceed the free tier (10,000 per month) without billing, bots start getting through, so keep an eye on usage

Related articles:

Questions about WordPress? The publisher of this site is based in Japan and replies in Japanese. Contact (Japanese)

お気軽にご相談ください

お見積りへ お問い合わせへ
▲