Usage v1.0.0

Install, register, and configure

Developer setup for a Laravel + Filament host. Admin form-building steps are in Workflows.

Requirements

Composer name: spiggle/form-builder. Namespace: Spiggle\FormBuilder. Plugin id: spiggle-form-builder.

Install (path repository)

{
  "repositories": [
    {
      "type": "path",
      "url": "packages/spiggle-form-builder",
      "options": { "symlink": true }
    }
  ],
  "require": {
    "spiggle/form-builder": "*"
  }
}
composer require spiggle/form-builder:@dev

The service provider auto-registers. Livewire component name: form-builder.public-form.

Publish config, migrations, views

php artisan vendor:publish --tag=form-builder-config
php artisan vendor:publish --tag=form-builder-migrations
php artisan vendor:publish --tag=form-builder-views
php artisan migrate

Migrations also auto-load from the package. Tables: form_builder_forms, form_builder_submissions, form_builder_audit_logs (prefixed so they do not collide with a generic forms table). Publishing views is only needed if you want to restyle the public renderer.

For public file downloads on the public disk: php artisan storage:link.

Register the Filament plugin

Starter: app/Providers/Filament/AdminPanelProvider.php.

use Spiggle\FormBuilder\Filament\FormBuilderPlugin;

$panel
    ->plugin(\Spiggle\DynamicFields\Filament\DynamicFieldsPlugin::make()) // optional, recommended
    ->plugin(FormBuilderPlugin::make());

Registers two resources:

Public routing

Default: GET /forms/{path} (path can include slashes). Named route: form-builder.public. Only published and active forms resolve (scopePublished).

Environment:

PathResolver rejects reserved segments, existing form slugs/paths, and existing Laravel routes, then appends -f{4-char-hash} (example style: contact-us-f8a1).

Permissions / Shield

AuthorizesFormBuilder::check($key) uses the same fallback as Dynamic Fields: permission or super_admin; if the permission row does not exist yet, authenticated panel users keep access.

Config keyDefault permissionUsed for
manage_formsmanage_formsForms resource
view_submissionsview_form_submissionsSubmissions resource (or manage_forms)
export_submissionsexport_form_submissionsExport actions
manage_submissionsmanage_form_submissionsReserved for host policies
php artisan shield:generate --all

Then assign those permissions to the roles that should manage forms vs only view/export submissions.

Artisan commands

CommandWhat it does
php artisan form-builder:seed Seeds Contact Us, Event Registration, Job Application, Customer Feedback (plus sample submissions). --fresh deletes those slugs first.
php artisan form-builder:verify Checks tables, FieldCatalog, builder UX contracts, validation, sanitization, clone, routing, CSV/XLSX/PDF export.
php artisan form-builder:export Portable JSON documents. Options: --slug=, --path= (default storage/app/form-builder-export.json).
php artisan form-builder:import {path} Import documents. --publish marks them published. New unique slugs/paths are generated.

Configuration

Published file: config/form-builder.php.

KeyDefaultPurpose
schema_version1.0Portable document version
route_prefixformsPublic URL prefix
root_pathsfalseVanity root interceptor
reserved_pathsadmin, livewire, api, up, storage, vendorNever used as form paths
submissions.statusesnew, reviewed, archived, spamInbox statuses
submissions.store_iptrueStore request IP
submissions.hash_ipfalseSHA-256 the IP if stored
submissions.store_user_agenttrueUA truncated to 512 chars
submissions.sanitize_htmltrueStrip tags; rich fields keep a small whitelist
files.disk / directory / max_size_kbpublic, form-submissions, 5120Public file uploads
exports.disk / directory / queue / formatslocal, form-builder-exports, default, csv/xlsx/pdfExport files
notify.enabled / mail_fromtrue, nullReserved for host mailers — see Features
container_typessingle, wizard, tabs, pagesLayouts
label_positionsabove, inline, below, insidePublic labels
field_typessame list as Dynamic FieldsUsed when Dynamic Fields is absent
drafts.enabled / session_keytrue, form_builder_draftsWizard/pages session drafts
validation_hooks(unset)Optional callable fn (Form, $rules): array

Useful PHP API

use Spiggle\FormBuilder\Models\Form;

$form = Form::query()->published()->where('base_path', 'contact-us')->first();
$form->publicUrl();
$form->document();          // portable JSON object
$form->fields();            // flattened field arrays
$form->cloneForm();         // unpublished copy, new path
$form->importCustomFields([1, 2, 3]); // Dynamic Fields ids

app(\Spiggle\FormBuilder\Services\SubmissionManager::class)
    ->capture($form, $data, request(), ['source' => 'api']);