Weave Code
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

Laravel Laravel Package

captchaapi/laravel

Official Laravel SDK for captchaapi.eu (EU-hosted, GDPR-friendly proof-of-work CAPTCHA). Includes Blade widget/component, server-side verification + validation rule, and optional Livewire 4 support. PHP 8.2+, Laravel 12/13.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require captchaapi/laravel
    php artisan vendor:publish --tag=captchaapi-config
    

    Add credentials to .env:

    CAPTCHAAPI_SITE_KEY=pk_live_...
    CAPTCHAAPI_SECRET_KEY=sk_live_...
    
  2. First Use Case (HTML Form):

    • Add the widget to your layout <head>:
      <x-captchaapi::widget />
      
    • Mark your form with data-captcha:
      <form method="POST" data-captcha>
          @csrf
          <!-- form fields -->
      </form>
      
    • Validate the response:
      $request->validate([
          'captchaapi_response' => ['required', 'captcha'],
      ]);
      
  3. First Use Case (Livewire):

    • Include the widget in your layout (same as above).
    • Use the WithCaptcha trait in your Livewire component:
      use Captchaapi\Laravel\Concerns\WithCaptcha;
      
      class MyComponent extends Component {
          use WithCaptcha;
      
          public function submit() {
              $this->validateWithCaptcha(['field' => 'required']);
              // Proceed...
          }
      }
      
    • Use the Livewire form wrapper in your view:
      <x-captchaapi::livewire-form action="submit">
          <!-- form fields -->
      </x-captchaapi::livewire-form>
      

Implementation Patterns

Workflows

  1. Form Submission Workflow:

    • HTML Forms: Use data-captcha on the <form> and validate with the captcha rule.
    • Livewire: Use validateWithCaptcha() in your component method and the livewire-form wrapper in your view.
    • Error Handling: Display errors with <x-captchaapi::error /> or manually with @error('captchaapi_response').
  2. Dynamic Form Integration:

    • For dynamically loaded forms (e.g., via AJAX), ensure the widget script is loaded before form interaction. Use CAPTCHAAPI_PRELOAD=eager in .env to preload the widget on page load.
  3. Multi-Step Forms:

    • Use validateWithCaptcha() in each step’s submission method. The captchaapi_response is automatically included in the validation.
  4. Conditional CAPTCHA:

    • Disable CAPTCHA for specific forms by conditionally rendering the widget or using middleware to skip validation:
      if (!$shouldUseCaptcha) {
          $request->validateWithoutCaptcha(['field' => 'required']);
      }
      

Integration Tips

  1. Livewire Integration:

    • Always use <x-captchaapi::livewire-form> instead of plain <form> to ensure proper event handling.
    • For custom Livewire actions, use rulesForCaptcha() to manually compose validation rules:
      $this->validate(array_merge($rules, $this->rulesForCaptcha()));
      
  2. Status Feedback:

    • Add a status element to provide user feedback:
      <div data-captcha-status></div>
      
    • Style it using the provided CSS classes or override defaults with custom CSS.
  3. Configuration:

    • Adjust CAPTCHAAPI_TIMEOUT for slower networks or CAPTCHAAPI_FAIL_OPEN for sensitive actions (e.g., logins).
    • Set CAPTCHAAPI_LOCALE to enforce a specific language for the widget.
  4. Testing:

    • Use FakeCaptchaapi::enable() in tests to bypass real API calls:
      use Captchaapi\Laravel\Testing\FakeCaptchaapi;
      
      beforeEach(function () {
          FakeCaptchaapi::enable();
      });
      
    • For Fortify testing, enforce single-use behavior:
      FakeCaptchaapi::enforceSingleUse();
      

Gotchas and Tips

Pitfalls

  1. Missing Widget Script:

    • Forgetting to include <x-captchaapi::widget /> in your layout will cause the CAPTCHA to fail silently. Always include it in the <head> of layouts where forms are used.
  2. Livewire Event Mode:

    • If using Livewire, ensure data-captcha-mode="event" is set by using <x-captchaapi::livewire-form>. Manual forms with data-captcha will use submit mode, which may not work with Livewire’s event-driven flow.
  3. Secret Key Exposure:

    • Never expose CAPTCHAAPI_SECRET_KEY in client-side code. The package is designed to keep it server-side only.
  4. Double Validation in Fortify:

    • Fortify validates login forms twice in a single request. Use FakeCaptchaapi::enforceSingleUse() in tests to simulate this behavior and avoid false positives.
  5. Status Element Overrides:

    • If you override the widget’s default colors with data-captcha-no-color, ensure you distinguish between waiting and ready states visually, as they share the same icon by default.

Debugging

  1. Validation Errors:

    • If ValidCaptcha fails unexpectedly, check:
      • The captchaapi_response field name in your form.
      • The .env keys (CAPTCHAAPI_SITE_KEY and CAPTCHAAPI_SECRET_KEY).
      • The CAPTCHAAPI_ENABLED flag (set to false disables validation silently).
  2. Livewire Debugging:

    • Use dd($this->rulesForCaptcha()) to inspect the generated CAPTCHA rules.
    • Check browser console for CAPTCHA widget errors (e.g., network issues or invalid responses).
  3. API Issues:

    • If the CAPTCHA service is unreachable, set CAPTCHAAPI_FAIL_OPEN=false to block submissions during outages. Monitor logs for timeout errors.
  4. Status Element Not Updating:

    • Ensure the <div data-captcha-status> is a direct child of the form or nearby in the DOM. The widget only styles elements with this attribute.

Extension Points

  1. Custom Validation Logic:

    • Extend the ValidCaptcha rule by creating a custom rule class:
      use Captchaapi\Laravel\Rules\ValidCaptcha as BaseValidCaptcha;
      
      class CustomValidCaptcha extends BaseValidCaptcha {
          public function passes($attribute, $value) {
              // Custom logic
              return parent::passes($attribute, $value);
          }
      }
      
    • Use it in validation:
      $request->validate([
          'captchaapi_response' => ['required', new CustomValidCaptcha],
      ]);
      
  2. Custom Status Styling:

    • Override the default styles by targeting the data-captcha-state attribute:
      [data-captcha-status][data-captcha-state="ready"] {
          background-color: #d1fae5;
      }
      
  3. Testing Extensions:

    • Mock the CAPTCHA API responses in tests by extending FakeCaptchaapi:
      FakeCaptchaapi::fake([
          'response' => 'valid_token_123',
      ]);
      
  4. Dynamic Configuration:

    • Override config values dynamically in your service provider:
      $this->app->singleton('config', function ($app) {
          return array_merge(
              require __DIR__.'/../config/captchaapi.php',
              ['timeout' => 10] // Override timeout
          );
      });
      

Configuration Quirks

  1. CAPTCHAAPI_PRELOAD:

    • Set to eager to load the CAPTCHA widget immediately on page load (useful for single-page applications). Default (lazy) waits for form interaction.
  2. CAPTCHAAPI_DEBUG:

    • Enable (true) to log timing breakdowns in the browser console for debugging performance issues.
  3. CAPTCHAAPI_MODE:

    • Explicitly set to submit or event if you need to override the default behavior (e.g., for custom form handlers). Defaults to null (auto-detects based on context).
  4. Locale Fallback:

    • The widget falls back to the <html lang> attribute if CAPTCHAAPI_LOCALE is not set. Ensure your app’s locale is correctly configured.
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.
craftcms/url-validator
directorytree/privacy-filter-classifier
directorytree/privacy-filter
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi
splash/scopes
splash/toolkit
testo/output-teamcity
testo/bridge-symfony