codebar-ag/laravel-filament-json-field
A Filament form field for editing JSON in Laravel admin panels. It provides a dedicated JSON editor with formatting and validation, making structured data such as settings, metadata, and dynamic content easier to manage. Integrates cleanly into Filament resources and forms.
Install the package with Composer and (for Filament v3) register the assets if the package doesn't auto-load them:
composer require codebar-ag/laravel-filament-json-field
php artisan vendor:publish --tag="filament-json-field-assets" # only if required by your Filament version
Requirements to check before installing: your Filament major version (the 2025-07-15 release targets Filament v3/v4, so pin against your app's version) and PHP 8.1+. Start by reading the README's usage snippet, then open src/Forms/Components/JsonField.php — the public methods there define everything you can chain.
Add the field to any Filament form, typically one backed by a json/text column on your model:
use CodebarAg\FilamentJsonField\Forms\Components\JsonField;
JsonField::make('settings')
->label('Settings')
->columnSpanFull();
On the model, cast the column so Laravel round-trips arrays cleanly:
protected $casts = ['settings' => 'array'];
That's the minimal happy path: install → drop the component into a resource form → cast the column. First real use case is usually a "settings" or "metadata" JSON blob on a resource that's otherwise edited as raw textarea — this replaces the textarea with a proper editable JSON surface.
Resource form + array cast. The most common setup is a JSON column cast to array. If the component hands you a decoded array rather than a string, normalize both sides so the editor and the model agree:
JsonField::make('settings')
->formatStateUsing(fn ($state) => is_array($state)
? json_encode($state, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)
: $state)
->dehydrateStateUsing(fn ($state) => is_string($state)
? json_decode($state, true)
: $state);
This keeps pretty-printing in the UI while still storing structured data.
Settings pages and custom Filament pages. The field is not resource-specific — drop it into any Filament\Pages\Page or settings page form schema. Pair it with a ->helperText('Edit as JSON') and ->columnSpanFull() because JSON editors need horizontal room.
Modal actions and relation managers. Because it's a standard Filament form component, it works inside Action::make()->form([...]) and RelationManager forms too. Watch state shape carefully in repeaters: a JsonField inside a Repeater receives the item's sub-state, which may already be an array.
Validation. Combine the field's own JSON parsing with Laravel rules for required shape:
JsonField::make('settings')
->required()
->rules(['json']); // guards against malformed JSON on save
For schema-level guarantees, add a custom rule or a ->rule(fn ($state) => ...) closure that json_decodes and inspects keys, since json only validates syntax, not structure.
Seeding and fixtures. Because the field is just a form component, seed the underlying column with arrays and the editor will render them once your formatStateUsing (or the array cast) normalizes the state.
composer.json constraints against your filament/filament version before upgrading either.vendor:publish copied the dist files. Open the browser console first — a missing CodeMirror/editor bundle throws before any PHP error appears.[object Object], null, or an empty pane, the component is receiving an array where it expects a JSON string (or vice versa). Fix at the boundary with formatStateUsing/dehydrateStateUsing rather than in the model.null vs {} vs []. Empty DB values arrive as null; some editors treat that as "no value" and skip initializing. Default with ->default('{}') or normalize in formatStateUsing if the empty editor misbehaves.json rule and test by saving deliberately broken JSON — confirm the validation message appears instead of a 500 or a silent overwrite.->afterStateUpdated(fn ($state) => logger()->info($state)) or Livewire::test(...)->assertFormSet(...) in a feature test to see exactly what the field emits before it hits the database.resources/views after publishing to see the editor mount options if you need to tweak theme, height, or read-only mode.->disabled() or ->readOnly() on view-only contexts; verify the editor actually respects it in your Filament version rather than assuming — a disabled JSON editor that still allows edits is a nasty surprise.How can I help you explore Laravel packages today?