reCAPTCHA
YiiRocks/reCAPTCHA
recaptcha provides Google reCAPTCHA v2 and v3 field + server-side validation for your Yii Framework 3 applications.
Configuration
Set your site keys and secret keys via environment variables
or directly in config/params.php:
'yiirocks/recaptcha' => [
'siteKeyV2' => $_ENV['RECAPTCHA_SITE_KEY_V2'] ?? '',
'secretV2' => $_ENV['RECAPTCHA_SECRET_V2'] ?? '',
'siteKeyV3' => $_ENV['RECAPTCHA_SITE_KEY_V3'] ?? '',
'secretV3' => $_ENV['RECAPTCHA_SECRET_V3'] ?? '',
'verifyUrl' => 'https://www.google.com/recaptcha/api/siteverify',
'sendRemoteIp' => false,
'translation.category' => 'yii3-recaptcha',
],
Once configured, the field pulls the site key from the
registry automatically — no need to call
withSiteKey() in your view code.
reCAPTCHA v2 Field
use Yiisoft\FormModel\FormModel;
use YiiRocks\Recaptcha\RecaptchaV2Field;
use YiiRocks\Recaptcha\RecaptchaV2Theme;
use YiiRocks\Recaptcha\RecaptchaV2Size;
use YiiRocks\Recaptcha\RecaptchaV2Type;
echo RecaptchaV2Field::field($form, 'captcha')
->withTheme(RecaptchaV2Theme::Dark)
->withSize(RecaptchaV2Size::Compact)
->withType(RecaptchaV2Type::Audio)
->withId('my-captcha')
->withCallback('onSuccess')
->render();
reCAPTCHA v2 Options
-
withSiteKey(string)( from config ) Explicit site key override. Optional — pulled from config by default -
withId(string)( 'g-recaptcha-{uniqid}' ) Widget element ID -
withTheme(RecaptchaV2Theme)( Light )LightorDark -
withType(RecaptchaV2Type)( Image )ImageorAudio -
withSize(RecaptchaV2Size)( Normal )Normal,Compact, orInvisible -
withJsApiUrl(string)( Google CDN ) Custom JS API URL -
withCallback(string)( — ) JavaScript callback function name on successful verification -
withExpiredCallback(string)( — ) JavaScript callback function name when the CAPTCHA expires -
withErrorCallback(string)( — ) JavaScript callback function name when an error occurs
Inherited from InputField:
-
->name(string)— override the hidden input name (default: auto-derived from form model asFormName[attribute]) -
->inputId(?string)— override the hidden input ID (default: auto-generated unique ID)
Container (inherited from BaseField):
-
->containerTag(string)( 'div' ) Wrapper tag -
->containerClass(string ...)( 'mb-3' ) Wrapper CSS class(es) -
->useContainer(bool)( true ) Enable/disable wrapper -
->containerAttributes(array)— set all wrapper attributes -
->addContainerAttributes(array)— merge additional wrapper attributes
reCAPTCHA v3 Field
The token is fetched on form submit (not on page load),
preventing unexpected challenge popups. The form is auto-resolved
via closest("form") — no formId needed
when the hidden input is inside the form.
use Yiisoft\FormModel\FormModel;
use YiiRocks\Recaptcha\RecaptchaV3Field;
use YiiRocks\Recaptcha\RecaptchaV3Badge;
echo RecaptchaV3Field::field($form, 'captcha')
->withAction('login')
->withFormId('login-form')
->withBadge(RecaptchaV3Badge::Hidden)
->render();
reCAPTCHA v3 Options
-
withSiteKey(string)( from config ) Explicit site key override. Optional — pulled from config by default -
withAction(string)( '' ) Action name sent to Google (must match the rule'sactionif set) -
withFormId(string)( — ) Explicit form ID. When omitted the form is auto-resolved viaclosest("form") -
withBadge(RecaptchaV3Badge)( BottomRight )BottomRight,BottomLeft, orHidden -
withJsApiUrl(string)( Google CDN ) Custom JS API URL -
withTranslator(?TranslatorInterface)( from registry ) Translator for the hidden badge legal notice -
withExecuteTimeout(?int)( 15000 ms ) Fallback form submission timeout (null = disabled)
Inherited from InputField:
-
->name(string)— override the hidden input name (default: auto-derived from form model asFormName[attribute]) -
->inputId(?string)— override the hidden input ID (default: auto-generated unique ID)
Container (inherited from BaseField):
-
->containerTag(string)( 'div' ) Wrapper tag -
->containerClass(string ...)( 'mb-3' ) Wrapper CSS class(es) -
->useContainer(bool)( true ) Enable/disable wrapper -
->containerAttributes(array)— set all wrapper attributes -
->addContainerAttributes(array)— merge additional wrapper attributes
Hidden badge: When Badge::Hidden is selected, the legal notice text
("This site is protected by reCAPTCHA…") is displayed automatically and
translated when a translator is available (either via withTranslator() or
through RecaptchaRegistry).
Validation
Use attributes on your form model properties:
use YiiRocks\Recaptcha\RecaptchaV2Rule;
use YiiRocks\Recaptcha\RecaptchaV3Rule;
final class LoginForm
{
#[RecaptchaV2Rule]
public string $captcha = '';
#[RecaptchaV3Rule(
threshold: 0.5,
action: 'login',
)]
public string $captcha = '';
}
Important: If you set ->withAction('...') on the v3 field,
you must also set action: '...' on the rule with the same value.
If neither is set, no action is sent and the check is skipped entirely.
v3 rule parameters
-
threshold( 0.5 ) Minimum score (0.0 — 1.0) -
action( null ) Expected action name (skipped ifnull) -
message( 'The CAPTCHA verification failed.' ) Error message (translatable) -
scoreTooLowMessage( 'The CAPTCHA score is too low.' ) Error when score is below threshold -
actionMismatchMessage( 'The CAPTCHA action does not match.' ) Error when action doesn't match -
secret( null ) Custom secret (uses config default ifnull) -
sendRemoteIp( false ) Whether to include the user's IP in verification
Server-Side Verification
Use RecaptchaClient for manual verification:
use YiiRocks\Recaptcha\RecaptchaClient;
/** @var RecaptchaClient $client */
$result = $client->verify($token);
$result = $client->verifyV3($token);
$result = $client->verifyWithSecret($token, $secret);
$result->success; // bool
$result->score; // ?float (v3 only)
$result->action; // ?string (v3 only)
$result->errorCodes; // array
$result->hostname; // ?string
$result->challengeTs; // ?string
$config = $client->getConfig(); // RecaptchaConfig