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.
A configurable Livewire contact form for Laravel with optional model persistence and pluggable notify channels (mail, log, webhook).
Install via Composer:
composer require labrodev/contactable
Then run composer update labrodev/contactable.
Publish the config file:
php artisan vendor:publish --tag=contactable-config
Edit config/contactable.php:
| Key | Description |
|---|---|
| fields | Array of field definitions: key, type, label, placeholder, rules, messages. Use translation keys (e.g. contactable::fields.name.label) or your own keys; the view passes them through __() at render time. |
| model | Optional Eloquent model FQCN to store submissions (e.g. App\Models\ContactRequest). Set to null to skip persistence. |
| notify | Channel (mail, log, or webhook) and channel-specific options (mail to address, webhook URL, log path). |
| success_message | Flash message after a successful submit (translation key or literal string). |
| submit_button_text / submit_loading_text | Button labels (translation key or literal string). |
| redirect_route | Named route to redirect to after submit (e.g. 'contact'). Omit or null to stay on the current page. |
In your layout, include Livewire scripts and styles (@livewireScripts, @livewireStyles, or the Livewire stack). Then drop in the form with the Blade component:
<x-contactable />
Or use the Livewire component directly:
<livewire:contactable::contactable />
Publish the views to match your design system:
php artisan vendor:publish --tag=contactable-views
Edit:
resources/views/vendor/contactable/livewire/contactable.blade.php – Form markup and styling.resources/views/vendor/contactable/components/contactable.blade.php – Wrapper (e.g. card, grid).Published views override the package defaults.
All user-facing text (labels, placeholders, validation messages, success message, button text) is translated via Laravel’s __() helper at render time. Config holds translation keys (or literal strings); the view and component pass them through __() so the current locale is used.
The package ships with English in resources/lang/en.php under the contactable:: namespace. The default config uses keys such as:
contactable::fields.name.label, contactable::fields.name.placeholder, contactable::fields.name.required, contactable::fields.name.maxcontactable::fields.email.*, contactable::fields.message.*contactable::success_message, contactable::submit_button_text, contactable::submit_loading_textOption 1 – Publish and edit package lang
php artisan vendor:publish --tag=contactable-lang
This copies the package lang to lang/vendor/contactable/. Edit en.php or add a new locale (e.g. ua.php, de.php) with the same structure. Laravel will use the correct file based on config('app.locale') (and fallback locale).
Option 2 – Use your own keys
In config/contactable.php (after publishing config), set labels, messages, and button text to your own translation keys (e.g. 'label' => 'contact.form.name', 'success_message' => 'contact.form.success_message'). The view and component still call __() on these values, so your app’s lang files (e.g. lang/en.json, lang/ua.json) are used. No need to publish the package lang if you rely entirely on your own keys.
If you set contactable.model to an Eloquent model class, the package will create a record on each submission. Your model should have fillable (or guarded) attributes matching the field keys (e.g. name, email, message). Create your own migration for the table; the package does not ship one.
Built-in channels:
contactable.notify.mail.to (env: CONTACTABLE_MAIL_TO or falls back to MAIL_FROM_ADDRESS).storage/logs/contact-submissions.log; path configurable).contactable.notify.webhook.url (env: CONTACTABLE_WEBHOOK_URL). Timeout is configurable.Implement Labrodev\Contactable\Contracts\NotifierChannel (single method: send(ContactableData $data): void), then register it in config:
// config/contactable.php
'notify' => [
'channel' => 'postmark',
'channels' => [
'postmark' => \App\ContactChannels\PostmarkChannel::class,
],
// ... mail, log, webhook options as needed
],
Your class is resolved from the container (you can inject dependencies). The package merges your channels with the built-in ones, so you can override or add channels (e.g. postmark, telegram).
From the package root (e.g. after cloning or in a path repo):
composer install
composer test
composer pint
composer stan
MIT. See LICENSE.md.
How can I help you explore Laravel packages today?