Skip to content

Form Submissions ​

The built-in Contact form and Newsletter sections store every submission and list it in an Inbox in your panel. Nothing to wire up: drop the section on a page, publish, and messages start arriving.

Upgrading from 1.40 or earlier

The inbox needs the filamentcraft_submissions table. Run php artisan filamentcraft:upgrade to publish and run the new migration. Until you do, submissions are reported and dropped, and filamentcraft:doctor fails the Form submissions check.

What happens on submit ​

  1. The section checks the honeypot and the per-visitor rate limit.
  2. It validates the fields and fires ContactFormSubmitted or NewsletterSubscribed.
  3. The package's listener writes a row to filamentcraft_submissions (when forms.store is on) and mails the addresses in forms.notify (when set).
  4. The visitor sees the section's success message.

Storage and mail failures are reported through report() and never reach the visitor: the success state does not depend on your mail server being up.

Each row keeps the site, the published page the section sits on (when it sits on one), the section id, the type (contact or newsletter), the submitted fields, the visitor's IP address and browser, and when it was read.

The inbox ​

Inbox sits in the FilamentCraft navigation group, with a badge counting unread submissions.

  • Filter by type, by read state, and by site when you run more than one.
  • Open a submission to read it in full. Opening it marks it read.
  • Mark rows read or unread, or delete them, one at a time or in bulk.

The inbox follows the same tenancy rules as the rest of the panel: an operator only ever sees submissions of the sites they can access, and a URL pointing at another tenant's submission 404s. Deleting a site deletes its submissions.

To hide the inbox, or rename it:

php
FilamentCraftPlugin::make()
    ->withSubmissionsInbox(false)            // or config('filamentcraft.forms.inbox')
    ->submissionsNavigationLabel('Messages');

Mail notifications ​

Set forms.notify to get a plain email per submission. It takes one address, a comma-separated list, or an array:

dotenv
FILAMENTCRAFT_FORMS_NOTIFY="owner@example.com,sales@example.com"

The mail is a queued notification sent on demand, so it goes through your queue when one is configured and sends inline otherwise. Contact messages set Reply-To to the visitor, so replying from your mail client answers them directly.

Spam defence ​

Both forms ship with two cheap defences, on by default:

  • Honeypot. A hidden field people never see and bots fill in. A filled one gets the success message and is dropped: no row, no mail, no event.
  • Throttle. Each visitor (by IP address) may send forms.throttle submissions per minute per form type. The next one shows a "try again in N seconds" error on the form.
php
'forms' => [
    'throttle' => 5,     // null or 0 turns the limit off
    'honeypot' => true,
],

Using your own destination ​

The events always fire, so a listener of your own works alongside the inbox:

php
use FilamentCraft\Events\ContactFormSubmitted;
use Illuminate\Support\Facades\Event;

Event::listen(ContactFormSubmitted::class, function (ContactFormSubmitted $event): void {
    Crm::createLead($event->name, $event->email, $event->message);
});

When your listener is the only destination you want, turn storage off:

php
'forms' => [
    'store' => false,    // FILAMENTCRAFT_FORMS_STORE=false
],

With storage off and no listener bound, visitors would be told their message was sent while it goes nowhere. filamentcraft:doctor warns about exactly that: Form submissions are discarded, naming each published page that carries an affected section.

Configuration ​

KeyDefaultEffect
forms.storetrueWrite submissions to filamentcraft_submissions and the inbox.
forms.notifynullAddress, comma-separated list or array to mail per submission.
forms.throttle5Submissions per visitor per minute, per form type. null/0 = off.
forms.honeypottrueRender the hidden field and drop submissions that fill it.
forms.inboxtrueRegister the Inbox resource in the panel.

The Submission model can be swapped like any other through filamentcraft.models.submission (see Models & Keys), and its keys follow filamentcraft.database.key_type.