{"id":13423006,"url":"https://github.com/aerni/statamic-livewire-forms","last_synced_at":"2026-01-19T12:06:21.672Z","repository":{"id":39792727,"uuid":"362410188","full_name":"aerni/statamic-livewire-forms","owner":"aerni","description":"Supercharge your Statamic forms with Livewire","archived":false,"fork":false,"pushed_at":"2025-07-28T08:38:09.000Z","size":816,"stargazers_count":29,"open_issues_count":0,"forks_count":4,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-12-20T12:40:07.105Z","etag":null,"topics":["form-builder","livewire","statamic","statamic-addon","tailwindcss"],"latest_commit_sha":null,"homepage":"https://statamic.com/addons/aerni/livewire-forms","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aerni.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-04-28T09:24:49.000Z","updated_at":"2025-08-10T01:28:16.000Z","dependencies_parsed_at":"2023-02-18T10:30:52.730Z","dependency_job_id":"c511e9d2-0327-4a74-aaad-67c3c7cecd85","html_url":"https://github.com/aerni/statamic-livewire-forms","commit_stats":{"total_commits":389,"total_committers":5,"mean_commits":77.8,"dds":0.04884318766066842,"last_synced_commit":"470c9776f22a62a999a5922b282e5e8c28d689ea"},"previous_names":[],"tags_count":34,"template":false,"template_full_name":null,"purl":"pkg:github/aerni/statamic-livewire-forms","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aerni%2Fstatamic-livewire-forms","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aerni%2Fstatamic-livewire-forms/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aerni%2Fstatamic-livewire-forms/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aerni%2Fstatamic-livewire-forms/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aerni","download_url":"https://codeload.github.com/aerni/statamic-livewire-forms/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aerni%2Fstatamic-livewire-forms/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28567863,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-19T08:53:44.001Z","status":"ssl_error","status_checked_at":"2026-01-19T08:52:40.245Z","response_time":67,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["form-builder","livewire","statamic","statamic-addon","tailwindcss"],"created_at":"2024-07-30T23:01:05.202Z","updated_at":"2026-01-19T12:06:21.643Z","avatar_url":"https://github.com/aerni.png","language":"PHP","readme":"![Statamic](https://flat.badgen.net/badge/Statamic/5.0+/FF269E) ![Packagist version](https://flat.badgen.net/packagist/v/aerni/livewire-forms/latest) ![Packagist Total Downloads](https://flat.badgen.net/packagist/dt/aerni/livewire-forms)\n\n# Livewire Forms\nThis addon provides a powerful framework to use Statamic forms with Laravel Livewire. No more submitting your form with AJAX or dealing with funky client-side validation libraries. Livewire Forms is a powerhouse that will make your life soooo much easier!\n\n## Features\n- Use your Statamic form blueprints as a form builder\n- Real-time validation with fine-grained control over each field\n- No need for a client-side form validation library\n- One source of truth for your validation rules\n- Spam protection with Google reCAPTCHA v2 and honeypot field\n- Support for display conditions set in your form blueprint\n- Multi-site support; translate your form display labels, instructions, placeholders, etc.\n- Configured and styled form views\n\n## Installation\nInstall the addon using Composer:\n\n```bash\ncomposer require aerni/livewire-forms\n```\n\nPublish the config of the package (optional):\n\n```bash\nphp please vendor:publish --tag=livewire-forms-config\n```\n\n## Manually bundling Livewire and Alpine\n\nIf you are [manually bundling Livewire and Alpine](https://livewire.laravel.com/docs/installation#manually-bundling-livewire-and-alpine), you will also need to import the Livewire Forms scripts.\n\n### Full bundle\n\nThe `livewire-forms.js` script is the full bundle and contains all the forms logic and external libraries like Filepond.\n\n```diff\nimport { Livewire, Alpine } from '../../vendor/livewire/livewire/dist/livewire.esm';\nimport Clipboard from '@ryangjchandler/alpine-clipboard'\n+ import \"../../vendor/aerni/livewire-forms/resources/dist/js/livewire-forms.js\";\n+ import \"../../vendor/aerni/livewire-forms/resources/dist/css/livewire-forms.css\";\n\nAlpine.plugin(Clipboard)\n\nLivewire.start()\n```\n\n### Individual imports\n\nIf you want more control, you may import individual scripts instead. This can be useful if you don't want to use some of the provided integrations like Filepond. At the bare minimum you should import `form.js`.\n\n```diff\nimport { Livewire, Alpine } from '../../vendor/livewire/livewire/dist/livewire.esm';\nimport Clipboard from '@ryangjchandler/alpine-clipboard'\n+ import \"../../vendor/aerni/livewire-forms/resources/dist/js/form.js\";\n+ import \"../../vendor/aerni/livewire-forms/resources/dist/js/filepond.js\";\n+ import \"../../vendor/aerni/livewire-forms/resources/dist/css/filepond.css\";\n+ import \"../../vendor/aerni/livewire-forms/resources/dist/js/grecaptcha.js\";\n\nLivewire.start()\n```\n\nThen, add the `{{ livewire:styles }}` and `{{ livewire:scriptConfig }}` tags to your layout:\n\n```html\n\u003chtml\u003e\n    \u003chead\u003e\n        \u003c!-- Antlers --\u003e\n        {{ livewire:styles }}\n\n        \u003c!-- Blade --\u003e\n        @livewireStyles\n    \u003c/head\u003e\n    \u003cbody\u003e\n        \u003c!-- Antlers --\u003e\n        {{ livewire:scriptConfig }}\n\n        \u003c!-- Blade --\u003e\n        @livewireScriptConfig\n    \u003c/body\u003e\n\u003c/html\u003e\n```\n\nDon't forget to remove the `@formAssets` directive from your form views, as the styles and script are now included in your bundle:\n\n```diff\n- @formAssets\n```\n\n## Commands\n\nThere are a number of helpful commands to help you create views, themes and components:\n\n| Command                        | Description                            |\n| -------------------------------| -------------------------------------- |\n| `livewire-forms:setup`         | Step by step wizard to get you started |\n| `livewire-forms:view {name?}`  | Create a new Livewire form view        |\n| `livewire-forms:theme {name?}` | Create a new Livewire form theme       |\n| `livewire-forms:component`     | Create a new Livewire form component   |\n\n## Getting started\n\n### Prerequisite\n\nThe views of this addon are styled with [Tailwind CSS](https://tailwindcss.com/) and [@tailwindcss/forms](https://github.com/tailwindlabs/tailwindcss-forms). However, you are free to change the views however you please.\n\n### Run the setup command\n\nGo ahead and run the `livewire-forms:setup` command in your console. It will guide you through creating your first [view](https://github.com/aerni/statamic-livewire-forms#views) and [theme](https://github.com/aerni/statamic-livewire-forms#themes). Optionally, you may also create a [component](https://github.com/aerni/statamic-livewire-forms#components) for complete control of your form.\n\n```bash\nphp please livewire-forms:setup\n```\n\n### Render the form\n\nAdd the Livewire form component to your template and provide the handle of the Statamic form.\n\n```blade\n\u003c!-- Antlers --\u003e\n{{ livewire:form handle=\"contact\" }}\n\n\u003c!-- Blade --\u003e\n\u003clivewire:form handle=\"contact\"\u003e\n```\n\nYou can also dynamically render a form that was selected via Statamic's Form fieldtype:\n\n```blade\n\u003c!-- Antlers --\u003e\n{{ livewire:form :handle=\"field:handle\" }}\n\n\u003c!-- Blade --\u003e\n\u003clivewire:form :handle=\"field:handle\"\u003e\n```\n\nUse the `view` and `theme` parameters if you want to use a view or theme that is different from the defaults defined in `config/livewire-forms.php`.\n\n```blade\n\u003c!-- Antlers --\u003e\n{{ livewire:form :handle=\"field:handle\" view=\"contact\" theme=\"regular\" }}\n\n\u003c!-- Blade --\u003e\n\u003clivewire:form :handle=\"field:handle\" view=\"contact\" theme=\"regular\"\u003e\n```\n\n#### Available Properties\n\n| Property   | Description                                                           |\n| ---------- | --------------------------------------------------------------------- |\n| `handle`   | The handle of the form you want to use (required)                     |\n| `view`     | The component view you want to use (optional)                         |\n| `theme`    | The theme you want to use (optional)                                  |\n| `redirect` | Redirect the user to this URL after successfull submission (optional) |\n\n## Views\n\nViews are the entry point of your forms. You may use the same view for each form.\n\n### Creating a view\n\nUse the `livewire-forms:view` command to create a new view:\n\n```bash\nphp please livewire-forms:view\n```\n\n### Autoloading\n\nViews are autoloaded by the handle of a form. In the example below, it will try to load the `contact.blade.php` view. If it doesn't exist, it will fall back to the default view defined in `config/livewire-forms.php`.\n\n```blade\n{{ livewire:form handle=\"contact\" }}\n```\n\n### Blade Directives\n\nThere are a couple of blade directives you may use in your form views. The directives are aware of the form's theme and will render the views accordingly.\n\n| Directive                | Description                                                                      | View                      |\n| ------------------------ | -------------------------------------------------------------------------------- | ------------------------- |\n| `@formSection('handle')` | Render a specific form section, e.g., `@formSection('contact_information')`      | section.blade.php         |\n| `@formField('handle')`   | Render a specific form field, e.g., `@formField('first_name')`                   | field.blade.php           |\n| `@formView('view')`      | Render a specific view of the current theme, e.g., `@formView('messages.display')` | Whatever view you provide |\n\n### Customization Example\n\nSometimes you need more control over the markup of your form. Rather than relying on the form's blueprint, you may decide to go fully custom and render individual fields using the `@formField` directive.\n\n```blade\n@formField('name')\n```\n\nYou may also add or override field properties using an array as the second argument.\n\n```blade\n@formField('name', [\n    'display' =\u003e 'Your Name',\n    'tooltip' =\u003e 'Please enter your full name'\n])\n```\n\nYou can then access the properties in the field's view.\n\n```blade\n{{ $field-\u003edisplay }}\n{{ $field-\u003etooltip }}\n```\n\n## Themes\n\nThemes allow you to fully customize each individual form view. You may have any number of themes.\n\n### Creating a theme\n\nUse the `livewire-forms:theme` command to create a new theme:\n\n```bash\nphp please livewire-forms:theme\n```\n\n### Autoloading\n\nThemes are autoloaded by the handle of a form. In the example below, it will try to load the views of the `contact` theme. If the theme doesn't exist, it will fall back to the default theme defined in `config/livewire-forms.php`. If a single view of the selected theme doesn't exist, it will fall back to the default theme for that particular view.\n\n```blade\n{{ livewire:form handle=\"contact\" }}\n```\n\n\u003e **Good to know:** Future releases of this addon will likely introduce breaking changes to your views. In that case, you will have to manually update your views according to the changes.\n\n### Field Views\n\nBy default, each field will load the view by its type. For example, a `subscription` field of `type: radio` will load the `radio.blade.php` view.\n\nSometimes you may want to load a different view for a given field, like a fancy radio button group for selecting a subscription. Field views are autoloaded by the field's handle. In this example, you can simply create a `subscription.blade.php` view under the theme's `fields` folder to autoload your custom view.\n\nYou may manually override a field's view by adding `view: {the_name_of_the_view}` to the field's config in the blueprint.\n\n## Components\n\nSometimes, you need more control over your form. For instance, if you want to dynamically populate a select field's options. There are a couple of concepts that help you customize your form experience.\n\n#### Creating a component\n\nGet started by creating a new component. The following example will create a new form component in `app/Livewire/ContactForm.php`\n\n```bash\nphp please livewire-forms:component ContactForm\n```\n\n### Autoloading\n\nCustom components are autoloaded by matching the class name with the form's handle. In the example below, it will try to load the `App\\Livewire\\ContactForm.php` component. If this component doesn't exist, it will fall back to the default form component.\n\n```blade\n\u003c!-- Antlers --\u003e\n{{ livewire:form handle=\"contact\" }}\n\n\u003c!-- Blade --\u003e\n\u003clivewire:form handle=\"contact\"\u003e\n```\n\n\u003e**Note:** For the autoloading magic to work, the component's name needs to end with `Form`, e.g., `ContactForm.php.`\n\n### Explicit Loading\n\nYou can also explicitly load a custom component by name like you would with any other Livewire component. This is necessary if you need to pass additional custom properties to the component.\n\n```blade\n\u003c!-- Antlers --\u003e\n{{ livewire:contact-form my-custom-prop=\"value\" }}\n\n\u003c!-- Blade --\u003e\n\u003clivewire:contact-form my-custom-prop=\"value\"\u003e\n```\n\n### Field Models\n\nEach Statamic fieldtype is mapped to a Livewire Forms field model. Models are responsible for generating a field's properties like `view`, `display`, `instructions`, `options`, and so on. You can find the default mappings in `config/livewire-forms.php`.\n\nFor instance, all the fields of type `\\Statamic\\Fieldtypes\\Select::class` are bound to the `\\Aerni\\LivewireForms\\Fields\\Select::class` model. A field property is created for each model method ending with `Property`, e.g. `optionsProperty()` will generate an `options` property.\n\nTo change a field's default model, simply change the binding in the `models` property in your component:\n\n```php\nprotected array $models = [\n    \\Statamic\\Fieldtypes\\Select::class =\u003e \\App\\Fields\\Select::class,\n];\n```\n\nIf you want to change a model for a specific field only, simply use the field's handle as the key instead:\n\n```php\nprotected array $models = [\n    'products' =\u003e \\App\\Fields\\SelectProduct::class,\n];\n```\n\n\u003e**Tip:** You may change the default bindings in `config/livewire-forms.php`. If you have a fieldtype that's not supported by this addon, simply create a new model and add the binding to the config.\n\n### Hooks\n\nThere are a couple of hooks that let you modify fields and submission data at various lifecycle steps.\n\n#### Mounted Fields\n\nUse this hook to modify the fields after they are mounted.\n\n```php\npublic function mountedFields(Collection $fields): void\n{\n    $fields-\u003eget('name')-\u003edisplay('Your name');\n}\n```\n\n#### Form Submitted\n\nUse this hook to modify the form submission before it is processed by Statamic.\n\n```php\npublic function formSubmitted(Submission $submission): void\n{\n    $title = $submission-\u003eaugmentedValue('entry')-\u003evalue()-\u003etitle;\n\n    $submission-\u003eset('entry_title', $title);\n}\n```\n\n### Events\n\nThis addon dispatches the following Events.\n\n#### Form Submitted\n\nThe `form-submitted` Livewire and `FormSubmitted` Statamic event is dispatched right after the Form Submitted hook. You can listen to this event as follows.\n\n**Livewire**\n```js\n@script\n\u003cscript\u003e\n    $wire.on('form-submitted', () =\u003e {\n        //\n    });\n\u003c/script\u003e\n@endscript\n```\n\n**Statamic**\n`Statamic\\Events\\FormSubmitted`\n\n```php\npublic function handle(FormSubmitted $event)\n{\n    $event-\u003esubmission; // The Submission object\n}\n```\n\n### Customization Example\n\nIn the following example we want to dynamically generate the options of a select field based on the entries of a Statamic collection. We also want to change the view of the field because the design needs to be different to a regular select field. There are two ways to achieve our task. We can either create a `custom field model` or use the `hydratedFields` callback. Choose whichever route feels better to you.\n\n#### Using a custom field model\n\nWe start by creating a new `SelectProduct` field model class that extends the default `Select` model class. We then override the `optionsProperty` method to return our options from a collection. We also assign a different view using the `$view` class property.\n\n```php\nnamespace App\\Fields;\n\nuse Aerni\\LivewireForms\\Fields\\Select;\nuse Statamic\\Facades\\Entry;\n\nclass SelectProduct extends Select\n{\n    protected string $view = 'select_product';\n\n    public function optionsProperty(): array\n    {\n        return Entry::whereCollection('products')\n            -\u003emapWithKeys(fn ($product) =\u003e [$product-\u003eslug() =\u003e $product-\u003eget('title')])\n            -\u003eall();\n    }\n}\n```\n\nNext, we need to tell the form which field we want to use the `SelectProduct` model for. In our case, we only want to use the `SelectProduct` model for the select field with the handle `products`.\n\n```php\nnamespace App\\Livewire;\n\nuse Aerni\\LivewireForms\\Livewire\\Form;\n\nclass ContactForm extends Form\n{\n    protected array $models = [\n        'products' =\u003e \\App\\Fields\\SelectProduct::class,\n    ];\n}\n```\n\n#### Using the mountedFields hook\n\nInstead of defining a new field model, we can also achieve the same thing using the `mountedFields` hook.\n\n```php\nnamespace App\\Livewire;\n\nuse Aerni\\LivewireForms\\Livewire\\Form;\n\nclass ContactForm extends Form\n{\n    public function mountedFields(Collection $fields): void\n    {\n        $options = Entry::whereCollection('products')\n            -\u003emapWithKeys(fn ($product) =\u003e [$product-\u003eslug() =\u003e $product-\u003eget('title')])\n            -\u003eall();\n\n        $fields-\u003eget('products')\n            -\u003eoptions($options)\n            -\u003eview('select_product');\n    }\n}\n```\n\n#### Render the component\n\nLastly, we need to render our new `ContactForm` component in the template.\n\n```blade\n\u003c!-- Antlers --\u003e\n{{ livewire:form handle=\"contact\" }}\n\n\u003c!-- Blade --\u003e\n\u003clivewire:form handle=\"contact\"\u003e\n```\n\n## Validation\n\n### Validation Rules\n\nYou can use any validation rule you want. Simply add it to the field in the form blueprint or use the blueprint builder in the CP.\n\nTo validate against the value of another field, you need to get its value like in the following example:\n\n```yaml\nvalidate:\n  - 'required_if:fields.newsletter.value,true'\n```\n\n### Real-time Validation\n\nReal-time validation works out of the box by updating the field's value on [change event](https://livewire.laravel.com/docs/wire-model#updating-on-change-event). You may override this behavior by setting the `wire_model` parameter in the field's config.\n\n```yaml\ntabs:\n  main:\n    display: Main\n    sections:\n      -\n        fields:\n          -\n            handle: email\n            field:\n              type: text\n              wire_model: live.debounce.150ms\n              validate:\n                - required\n                - email\n```\n\nTo use Livewire's default behavior and defer all network requests until the form is submitted, you may set `wire_model: defer`.\n\n### Validation Messages\n\nYou can customize the validation messages of your fields by creating a [custom form component](#components) and using either of the two methods below.\n\n\u003e**Note:** Make sure to add `data` in front of the field's handle.\n\n#### Using the `$messages` property\n\n```php\nprotected $messages = [\n    'fields.name.value.required' =\u003e 'What is your name, darling?',\n];\n```\n\n#### Using the `messages()` method\n\n```php\nprotected function messages(): array\n{\n    return [\n        'fields.name.value.required' =\u003e 'What is your name, darling?',\n    ];\n}\n```\n\n## Localization\n\nThere are a few default message strings, like the `submit button label` and `success message` that you might want to change. You can change the messages globally or on a per-form level.\n\n### Globally\n\nPublish the language files and change whatever message you'd like:\n\n```bash\nphp artisan vendor:publish --tag=livewire-forms-translations\n```\n\n### Per Form\n\n1. Create a file called `livewire-forms.php` for each of your localizations, e.g., `resources/lang/en/livewire-forms.php`.\n2. Create an array with the handle of each form for which you want to change a message for.\n3. Use the same keys that are used in the global language files. Note, that the messages in this file will take precedence over the messages in the global language file.\n\n```php\nreturn [\n\n    'contact' =\u003e [\n        'submit_button_label' =\u003e 'Contact now',\n        'success_message' =\u003e 'Thanks for contacting us. We will be in touch.',\n        'error_message' =\u003e 'There was an error with your submission:|There were :count errors with your submission:',\n    ],\n\n    'newsletter' =\u003e [\n        'submit_button_label' =\u003e 'Signup now',\n    ],\n\n];\n```\n\n### Translating sections and fields\n\nYou can translate your field display labels, instructions, options, and placeholders using JSON files. Create a translation file for each language, e.g. `resources/lang/de.json`.\n\n### Example\n\n**Form Blueprint**\n```yaml\ntabs:\n  main:\n    display: Main\n    sections:\n      -\n        display: Subscription\n        instructions: 'Choose your subscription below'\n        fields:\n          -\n            handle: subscription\n            field:\n              display: Subscription\n              placeholder: 'Which subscription do you want?'\n```\n\n**Translation File**\n```json\n{\n    \"Subscription\": \"Abo\",\n    \"Choose your subscription below\": \"Wähle dein Abo\",\n    \"Which subscription do you want?\": \"Welches Abo möchtest du?\",\n}\n```\n\n## Captcha Fieldtype\n\nThis addon comes with a `Captcha` fieldtype that lets you add a `Google reCAPTCHA v2 (checkbox)` captcha to your form. The Captcha fieldtype is available in the form blueprint builder like any other fieldtype.\n\n\u003e**Note:** Make sure to add your captcha key and secret in your `.env` file.\n\n## License\nLivewire Forms is **commercial software** but has an open-source codebase. If you want to use it in production, you'll need to [buy a license from the Statamic Marketplace](https://statamic.com/addons/aerni/livewire-forms).\n\u003eLivewire Forms is **NOT** free software.\n\n## Credits\nDeveloped by[ Michael Aerni](https://www.michaelaerni.ch)\n","funding_links":[],"categories":["Forms"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faerni%2Fstatamic-livewire-forms","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faerni%2Fstatamic-livewire-forms","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faerni%2Fstatamic-livewire-forms/lists"}