Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Recaptcha Laravel Package

greggilbert/recaptcha

A Laravel package that integrates Google reCAPTCHA into forms and validation. It provides a validation rule, Blade helpers, configuration options, and server-side response verification, making it simple to add reliable spam protection to your application.

View on GitHub
Deep Wiki
Context7

Getting Started

This package is a Laravel 5-era bridge between a form and Google's reCAPTCHA v1 API. It is marked abandoned upstream and its last tagged release was February 2016, so treat "getting started" as onboarding onto a legacy codebase rather than evaluating a dependency for new work.

Minimal setup in an existing Laravel 5.x app:

composer require greggilbert/recaptcha

Register the service provider and facade in config/app.php:

'providers' => [
    Greggilbert\Recaptcha\RecaptchaServiceProvider::class,
],
'aliases' => [
    'Recaptcha' => Greggilbert\Recaptcha\Facades\Recaptcha::class,
],

Publish the config so the keys are editable:

php artisan vendor:publish --provider="Greggilbert\Recaptcha\RecaptchaServiceProvider"

That produces config/recaptcha.php with a public_key, a private_key, and an options array (theme/language/tabindex) that is passed straight through to the widget markup. Pull those values from env() rather than committing them.

The first use case is always the same: a contact or registration form. Render the widget in Blade with {!! Recaptcha::render() !!}, then attach the package's custom validation rule to the response field:

$validator = Validator::make($request->all(), [
    'recaptcha_response_field' => 'required|recaptcha',
]);

Where to look first when something is wrong:

  1. config/recaptcha.php — key/option mismatches cause 90% of failures.
  2. The service provider in src/ — confirms the validator extension name and how the rule is bound.
  3. The Recaptcha class — this is where render() builds markup and where the outbound HTTP verification call happens.
  4. The validator class — confirms exactly which request keys (recaptcha_challenge_field, recaptcha_response_field) it reads.

If you are starting a new project, stop here and use a maintained v3 package instead; the sections below only make sense for maintenance work on an existing install.

Implementation Patterns

Render through a partial, not inline. In a legacy app the widget markup tends to get copy-pasted into every form. Wrap it once:

{{-- resources/views/partials/recaptcha.blade.php --}}
@unless(app()->environment('testing'))
    {!! Recaptcha::render() !!}
@endunless

Then @include('partials.recaptcha') in each form. This gives you a single place to swap vendors later.

Per-form option overrides. render() accepts an array that merges over the config options, so a dark-themed login form and a light-themed contact form can coexist without touching config:

{!! Recaptcha::render(['theme' => 'dark']) !!}

FormRequest integration. The rule is a plain string rule, so it drops into a rules() array unchanged:

public function rules()
{
    return [
        'name'  => 'required|max:255',
        'email' => 'required|email',
        'recaptcha_response_field' => 'required|recaptcha',
    ];
}

Keep required first. The package's rule does not imply presence, and the error message for a missing field is more useful from required.

Customising the error message. The rule resolves its message from the package's translation namespace. Either publish/override the lang file, or add a recaptcha key to resources/lang/en/validation.php:

'recaptcha' => 'Please confirm you are human.',

Testing. The validator performs a live HTTP call to Google on every run, which makes feature tests slow and flaky. Two workable patterns:

// Bypass at the facade level
Recaptcha::shouldReceive('validate')->once()->andReturn(true);

// Or globally short-circuit in the test suite
Validator::extend('recaptcha', fn() => true);

Prefer the second in TestCase::setUp() so you don't have to remember it in every test.

Migration shim. The most useful day-to-day pattern for an abandoned validator is to keep the rule name and swap the implementation behind it. Rebind the validator in a service provider to call the v2 siteverify endpoint with g-recaptcha-response, then update only the Blade partial and the field name. Your FormRequests and controllers stay untouched, which is what makes the migration a one-afternoon job instead of a rewrite.

AJAX/SPA forms. The widget contributes two hidden inputs in v1. If you submit via $.post, serialize the whole form rather than hand-picking fields, or the validator will receive nulls and fail with a misleading error.

Gotchas and Tips

The big one: reCAPTCHA v1 is dead. Google shut the v1 API down on 31 March 2018. The endpoint this package calls no longer issues challenges, and keys can no longer be generated. A fresh install will render an empty box or an error iframe, and validation will always fail. Any "it doesn't work" report on this package is almost certainly this, not a configuration problem.

Abandonment surface area. No releases since Feb 2016 means no Laravel 6+ support, no PHP 7.4/8 compatibility (expect failures around array_get-style helpers, old contract signatures, and possibly dynamic properties), and no security patches. Pin the dependency and plan the exit.

HTTP, not HTTPS. Older builds of this package hit http://www.google.com/recaptcha/api/verify. On an HTTPS site that is a mixed-content or redirect failure. If you must keep it alive briefly, patch the URL to https://.

allow_url_fopen. The package uses a simple stream/file-get-contents style request rather than Guzzle. Hosts with allow_url_fopen = Off will fail verification silently — you get a validation failure, not an exception. This is the single most confusing failure mode to debug because the error message is identical to "user typed the wrong word."

Config caching. php artisan vendor:publish writes keys once; after that, edits to config/recaptcha.php are invisible while bootstrap/cache/config.php exists. Always php artisan config:clear when a key change "doesn't take."

Facade and rule registration errors. Class 'Recaptcha' not found means the alias is missing from config/app.php. Method [validateRecaptcha] does not exist means the service provider isn't registered, or a second provider overrode the validator. Both are copy-paste mistakes in the install steps, not package bugs.

Two keys, easily confused. public_key drives the rendered widget; private_key is only used server-side. Swapping them produces a widget that renders but never verifies — and vice versa.

Empty options array. If you hand render() an options array with a null value, it is emitted as an empty data-* attribute and Google may ignore or reject the widget. Filter nulls before passing.

Extension points are limited but real. You can Validator::extend('recaptcha', ...) to override the rule wholesale, bind your own class to the container, or replace the facade accessor. There is no pluggable transport and no events, so anything beyond swapping the verification call means forking.

Don't try to modernise it in place. reCAPTCHA v3 is score-based and has no user-facing widget, which breaks the render() + hidden-field contract this package is built around. The clean path is biscolab/laravel-recaptcha or josiasmontag/laravel-recaptcha, with the shim pattern above to keep your form code stable.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle