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

Contactable Laravel Package

labrodev/contactable

Configurable Livewire contact form for Laravel. Define fields in config, optionally persist submissions to an Eloquent model, and send notifications via mail, log, or webhook. Supports published views and translation-ready labels/messages.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require labrodev/contactable
    php artisan vendor:publish --tag=contactable-config
    

    Publish the default config (config/contactable.php) and update it to match your needs.

  2. Basic Blade Integration: Add the Livewire component to your form:

    @livewire('contactable::contact-form')
    
  3. First Use Case:

    • Configure a simple form with name, email, and message fields in config/contactable.php:
      'fields' => [
          'name' => [
              'type' => 'text',
              'label' => 'contactable::fields.name.label',
              'rules' => 'required|string|max:255',
          ],
          'email' => [
              'type' => 'email',
              'label' => 'contactable::fields.email.label',
              'rules' => 'required|email',
          ],
          'message' => [
              'type' => 'textarea',
              'label' => 'contactable::fields.message.label',
              'rules' => 'required|string',
          ],
      ],
      
    • Set up a notification channel (e.g., mail):
      'notify' => [
          'channel' => 'mail',
          'options' => [
              'to' => 'contact@example.com',
          ],
      ],
      
    • Include the component in your Blade view and submit the form.

Implementation Patterns

Workflows

  1. Dynamic Field Configuration: Extend or override the default fields in config/contactable.php or via a service provider:

    Contactable::configure(function ($config) {
        $config->fields['phone'] = [
            'type' => 'tel',
            'label' => 'Phone Number',
            'rules' => 'nullable|digits_between:10,15',
        ];
    });
    
  2. Model Persistence:

    • Define a model (e.g., App\Models\ContactRequest) with fillable fields matching your config.
    • Configure the model in config/contactable.php:
      'model' => App\Models\ContactRequest::class,
      
    • Customize the model further via an observer or accessor:
      ContactRequest::observe(ContactableObserver::class);
      
  3. Notification Channels:

    • Mail: Use Laravel’s mail system with customizable templates (e.g., resources/views/vendor/contactable/mail.blade.php).
    • Log: Log submissions to a file or channel:
      'notify' => [
          'channel' => 'log',
          'options' => [
              'path' => storage_path('logs/contactable.log'),
          ],
      ],
      
    • Webhook: Send submissions to an external API:
      'notify' => [
          'channel' => 'webhook',
          'options' => [
              'url' => 'https://api.example.com/webhook',
              'headers' => ['Authorization' => 'Bearer token'],
          ],
      ],
      
  4. Validation and Localization:

    • Use translation keys for labels/rules (e.g., contactable::validation.required).
    • Override translations in resources/lang/en/contactable.php:
      return [
          'fields' => [
              'name' => [
                  'label' => 'Full Name',
              ],
          ],
      ];
      
  5. Styling and Assets:

    • Customize the form’s appearance by publishing assets:
      php artisan vendor:publish --tag=contactable-assets
      
    • Override the default Blade view (resources/views/vendor/contactable/form.blade.php).

Integration Tips

  • Livewire Events: Listen for form submission events in your parent component:

    protected $listeners = ['contactable.submitted' => 'handleSubmission'];
    
    public function handleSubmission($data) {
        // Custom logic after submission
    }
    
  • Form Spam Protection: Add reCAPTcha or honeypot fields via the fields config:

    'fields' => [
        'honeypot' => [
            'type' => 'hidden',
            'rules' => 'required|ignore',
        ],
    ],
    
  • API Endpoints: For headless use, create a Livewire action to submit via JavaScript:

    Livewire.emit('contactable.submit', { name: 'John', email: 'john@example.com' });
    
  • Testing: Use Livewire’s testing helpers to simulate submissions:

    $this->livewire(Contactable::class)
         ->fillForm([
             'name' => 'Test User',
             'email' => 'test@example.com',
             'message' => 'Hello!',
         ])
         ->call('submit')
         ->assertEmitted('contactable.submitted');
    

Gotchas and Tips

Pitfalls

  1. Field Key Conflicts: Ensure key values in fields are unique and match your model’s fillable fields if using persistence. Overlapping keys may cause validation or storage issues.

  2. Notification Channel Errors:

    • Mail: Verify the to address is valid and the mail driver is configured in Laravel.
    • Webhook: Check the url and headers for typos or CORS issues. Use try-catch in the webhook handler:
      try {
          Http::post($url, $data)->throw();
      } catch (\Throwable $e) {
          Log::error("Webhook failed: " . $e->getMessage());
      }
      
    • Log: Ensure the path is writable and the directory exists.
  3. Livewire Component Registration: If using the component outside the contactable namespace, register it in AppServiceProvider:

    Livewire::component('contact-form', \Labrodev\Contactable\Livewire\ContactForm::class);
    
  4. CSRF Token Mismatch: Ensure the form includes @csrf and the Livewire component is loaded after @livewireScripts.

  5. Translation Fallback: If using custom translation keys, ensure they exist in your language files or fall back to the default:

    'label' => __('contactable::fields.name.label', [], 'en'), // Fallback to English
    

Debugging

  1. Validation Errors: Check the Livewire component’s errors property or log them:

    Log::debug('Validation errors:', $this->errors->all());
    
  2. Submission Data: Log the submitted data in the handleSubmit method of the Livewire component (extend if needed):

    protected function handleSubmit(array $data): void
    {
        Log::debug('Submitted data:', $data);
        // ... rest of the logic
    }
    
  3. Configuration Overrides: Use php artisan config:clear after updating config/contactable.php to apply changes.


Extension Points

  1. Custom Validation: Extend the Livewire component to add dynamic rules:

    public function mount()
    {
        $this->rules['custom_field'] = 'required_if:other_field,1|string';
    }
    
  2. Additional Channels: Add a new notification channel by implementing Labrodev\Contactable\Contracts\NotifyChannel:

    class SlackChannel implements NotifyChannel
    {
        public function notify(array $data): void
        {
            // Send to Slack
        }
    }
    

    Register it in the config:

    'notify' => [
        'channel' => 'slack',
        'options' => ['webhook_url' => env('SLACK_WEBHOOK')],
    ],
    
  3. Model Events: Listen for creating or created events on your model to add metadata (e.g., IP address):

    ContactRequest::created(function ($request) {
        $request->ip_address = request()->ip();
    });
    
  4. Asset Overrides: Publish and override the default CSS/JS:

    php artisan vendor:publish --tag=contactable-assets --force
    

    Customize resources/vendor/contactable/assets/contactable.css.

  5. Multi-Step Forms: Use Livewire’s wire:ignore and JavaScript to toggle steps dynamically, then submit via the component’s submit method.

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.
make-dev/orca
dmstr/symfony-system-resources-bundle
dmstr/symfony-job-queue-bundle
dmstr/openapi-json-schema-bundle
dmstr/keycloak-security-bundle
dmstr/doctrine-audit-log-bundle
dmstr/api-platform-utils-bundle
dmstr/api-configuration-bundle
chrisdev/ux-components
baks-dev/finances
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle