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

Spam Protection Bundle Laravel Package

florentingarnier/spam-protection-bundle

A Symfony bundle by Florentin Garnier that adds configurable spam protection to forms, helping block bot submissions and reduce junk input with minimal setup in Symfony applications.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Start with the README and composer.json: this is a Symfony Form-oriented spam-protection package, not a Laravel package with a service provider or publishable Laravel config. The v0.2.2 release adds symfony/translation-contracts and fixes the rejection message so it is translated instead of rendering the raw key florentin_garnier_spam_protection.invalid.
  • If you are in a Laravel-only app, the practical first use case is to borrow the honeypot + submission-timing pattern and implement it in a FormRequest, middleware, or custom validation rule. Do not expect php artisan vendor:publish to expose package config.
  • If you are using Symfony Form inside a Laravel app, register the form extension/theme and ensure a Symfony-compatible translator is wired up. The first thing to verify is that FormError messages are translated before the form theme renders them.
  • Upgrade to v0.2.2 if you saw florentin_garnier_spam_protection.invalid shown directly to visitors. It is a patch-level release with no apparent breaking changes.

Implementation Patterns

  • Symfony Form usage: enable the package’s form extension, render the hidden spam-protection field in the form, and let the package attach a FormError using the florentin_garnier_spam_protection.invalid translation key. Customize the message by overriding the translation catalog, not by replacing the key with a hard-coded string.
  • Laravel-native equivalent: centralize the check in a reusable validation rule or FormRequest:
class SpamProtection implements ValidationRule
{
    public function validate(string $attribute, mixed $value, Closure $fail): void
    {
        if (request()->filled('_honeypot')) {
            $fail(__('florentin_garnier_spam_protection.invalid'));
        }

        $submittedAt = (int) request('_submitted_at', 0);

        if ($submittedAt === 0 || now()->timestamp - $submittedAt < 3) {
            $fail(__('florentin_garnier_spam_protection.invalid'));
        }
    }
}
  • Add a Laravel language file such as lang/en/florentin_garnier_spam_protection.php with an invalid key, then render errors normally in Blade with @error.
  • Day-to-day workflow: put the hidden honeypot field and signed timestamp in a shared Blade component, apply the validation rule to public forms, log rejected submissions with IP/user agent/referrer, and add feature tests for “bot fills honeypot” and “submitted too quickly”.
  • If using the actual package with Symfony Form, ensure the form theme renders FormError messages after translation. Keep the package translation domain intact so overrides remain predictable.
  • Integration tip: do not rely on the hidden field alone. Combine it with rate limiting, Laravel’s throttle middleware, CSRF protection, and content checks. The package pattern is a low-friction first line of defense, not a complete anti-spam system.

Gotchas and Tips

  • v0.2.2 fixed the raw translation-key rendering, but the key remains the message template. If you override the message, override the translation entry rather than setting a translated string as the error key.
  • The added symfony/translation-contracts dependency matters if you try to use this with Laravel’s translator. Laravel’s translator does not implement Symfony’s translator interfaces, so Symfony FormError translation may not use Laravel’s __() catalog automatically. You need an adapter or the Symfony Translation component if you use Symfony Form directly.
  • Clear the relevant caches after changing translations. In Symfony, use bin/console cache:clear; in Laravel, php artisan cache:clear and php artisan config:clear may be needed depending on how you bridge the translator.
  • Hidden honeypot fields can be autofilled by password managers or accessibility tools. Use autocomplete="off", tabindex="-1", aria-hidden="true", and keep the field visually hidden rather than type="hidden" where possible.
  • Timing checks can reject fast legitimate users. Keep the minimum threshold low, document it, and avoid using timing as the only signal.
  • Debugging: inspect the FormError message before rendering to confirm whether it is a key or translated text. In Symfony, debug:translation helps; in Laravel, verify __('florentin_garnier_spam_protection.invalid') resolves as expected.
  • Extension points are mainly the translation catalog and package configuration if exposed by the bundle. If you need Laravel-native behavior, port the pattern into a validation rule or middleware rather than forcing a Symfony Form integration into a typical Laravel request lifecycle.
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.
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
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