PHPackages                             labrodev/contactable - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. labrodev/contactable

ActiveLaravel-package[Utility &amp; Helpers](/categories/utility)

labrodev/contactable
====================

Configurable Livewire contact form with optional model persistence and notify channels.

v1.0.0(4mo ago)080MITPHPPHP ^8.2

Since Mar 13Pushed 4mo agoCompare

[ Source](https://github.com/labrodev/contactable)[ Packagist](https://packagist.org/packages/labrodev/contactable)[ RSS](/packages/labrodev-contactable/feed)WikiDiscussions main Synced 3w ago

READMEChangelogDependencies (6)Versions (2)Used By (0)

Labrodev Contactable
====================

[](#labrodev-contactable)

A configurable Livewire contact form for Laravel with optional model persistence and pluggable notify channels (mail, log, webhook).

Requirements
------------

[](#requirements)

- PHP 8.2+
- Laravel 12+
- Livewire 4+

Installation
------------

[](#installation)

Install via Composer:

```
composer require labrodev/contactable
```

Then run `composer update labrodev/contactable`.

Configuration
-------------

[](#configuration)

Publish the config file:

```
php artisan vendor:publish --tag=contactable-config
```

Edit `config/contactable.php`:

KeyDescription**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.Usage
-----

[](#usage)

In your layout, include Livewire scripts and styles (`@livewireScripts`, `@livewireStyles`, or the Livewire stack). Then drop in the form with the Blade component:

```

```

Or use the Livewire component directly:

```

```

View customization
------------------

[](#view-customization)

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.

Translations
------------

[](#translations)

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.

### Package lang (default)

[](#package-lang-default)

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.max`
- `contactable::fields.email.*`, `contactable::fields.message.*`
- `contactable::success_message`, `contactable::submit_button_text`, `contactable::submit_loading_text`

### Adding or overriding translations

[](#adding-or-overriding-translations)

**Option 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.

Optional model persistence
--------------------------

[](#optional-model-persistence)

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.

Notify channels
---------------

[](#notify-channels)

Built-in channels:

- **mail** – Sends an email to `contactable.notify.mail.to` (env: `CONTACTABLE_MAIL_TO` or falls back to `MAIL_FROM_ADDRESS`).
- **log** – Appends a line to a log file (default `storage/logs/contact-submissions.log`; path configurable).
- **webhook** – POSTs the submission JSON to `contactable.notify.webhook.url` (env: `CONTACTABLE_WEBHOOK_URL`). Timeout is configurable.

### Custom channels

[](#custom-channels)

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`).

Development
-----------

[](#development)

From the package root (e.g. after cloning or in a path repo):

```
composer install
composer test
composer pint
composer stan
```

License
-------

[](#license)

MIT. See [LICENSE.md](LICENSE.md).

###  Health Score

37

—

LowBetter than 81% of packages

Maintenance74

Regular maintenance activity

Popularity12

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity47

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

147d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/151143718?v=4)[Lashyn Petro ](/maintainers/labrodev)[@labrodev](https://github.com/labrodev)

---

Top Contributors

[![labrodev](https://avatars.githubusercontent.com/u/151143718?v=4)](https://github.com/labrodev "labrodev (1 commits)")

---

Tags

labrodevlaravellaravel-frameworklaravel-librarylaravel-packagelaravel12xlivewirephp-libraryphp8web

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/labrodev-contactable/health.svg)

```
[![Health](https://phpackages.com/badges/labrodev-contactable/health.svg)](https://phpackages.com/packages/labrodev-contactable)
```

###  Alternatives

[nasirkhan/laravel-starter

A CMS like modular Laravel starter project.

1.4k2.7k](/packages/nasirkhan-laravel-starter)[team-nifty-gmbh/tall-datatables

Server-side rendered datatables for Laravel and Livewire

1422.0k5](/packages/team-nifty-gmbh-tall-datatables)[tomshaw/electricgrid

A feature-rich Livewire package designed for projects that require dynamic, interactive data tables.

119.8k](/packages/tomshaw-electricgrid)[ramonrietdijk/livewire-tables

Dynamic tables for models with Laravel Livewire

21362.6k](/packages/ramonrietdijk-livewire-tables)[noerd/noerd

101.4k11](/packages/noerd-noerd)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
