Filament v4 Unified Schema API: Forms &amp; Infolists | Mohamed Said        [  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png)   Mohamed Said Laravel Backend Engineer  ](https://msaied.com) [ Home ](https://msaied.com) [ Projects ](https://msaied.com/projects) [ Articles  ](https://msaied.com/articles) [ Certificates ](https://msaied.com/certificates) [ Contact ](https://msaied.com#contact-section) 

       [  ](https://github.com/EG-Mohamed)       

 [ Home ](https://msaied.com) [ Projects ](https://msaied.com/projects) [ Articles ](https://msaied.com/articles) [ Certificates ](https://msaied.com/certificates) [ Contact ](https://msaied.com#contact-section) 

  [ home ](https://msaied.com)    [ articles ](https://msaied.com/articles)    Filament v4 Schema-Based Forms, Infolists, and the Unified Schema API        On this page       1. [  Why Filament v4 Rethinks the Component Tree ](#why-filament-v4-rethinks-the-component-tree)
2. [  The Schema Entry Point ](#the-schema-entry-point)
3. [  Explicit Infolist Overrides ](#explicit-infolist-overrides)
4. [  Extracting Reusable Schema Fragments ](#extracting-reusable-schema-fragments)
5. [  Conditional Visibility Without Duplication ](#conditional-visibility-without-duplication)
6. [  Testing the Unified Schema ](#testing-the-unified-schema)
7. [  Key Takeaways ](#key-takeaways)

  ![Filament v4 Schema-Based Forms, Infolists, and the Unified Schema API](https://cdn.msaied.com/501/98f4034a9cdbe0ac34480781384b9615.png)

  #filament   #laravel   #filament-v4   #admin-panels  

 Filament v4 Schema-Based Forms, Infolists, and the Unified Schema API 
=======================================================================

     2 Aug 2026      3 min read    ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said  

       Table of contents

1. [  01   Why Filament v4 Rethinks the Component Tree  ](#why-filament-v4-rethinks-the-component-tree)
2. [  02   The Schema Entry Point  ](#the-schema-entry-point)
3. [  03   Explicit Infolist Overrides  ](#explicit-infolist-overrides)
4. [  04   Extracting Reusable Schema Fragments  ](#extracting-reusable-schema-fragments)
5. [  05   Conditional Visibility Without Duplication  ](#conditional-visibility-without-duplication)
6. [  06   Testing the Unified Schema  ](#testing-the-unified-schema)
7. [  07   Key Takeaways  ](#key-takeaways)

 Why Filament v4 Rethinks the Component Tree
-------------------------------------------

Filament v3 kept forms and infolists as parallel but separate hierarchies. You defined `form(Form $form)` and `infolist(Infolist $infolist)` independently, duplicating field definitions whenever you wanted a read-only view alongside an editable one. Filament v4 collapses this into a **unified Schema API**: one component tree that can render in both contexts.

This is not a cosmetic change. It affects how you structure resources, build reusable field sets, and test panel behaviour.

---

The Schema Entry Point
----------------------

In v4, `Resource` classes expose a `schema()` method that returns a `Schema` instance. Both the form and the infolist delegate to it:

```php
use Filament\Schemas\Schema;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\DatePicker;
use Filament\Infolists\Components\TextEntry;

public static function schema(Schema $schema): Schema
{
    return $schema->components([
        TextInput::make('name')
            ->required()
            ->maxLength(255),

        DatePicker::make('published_at')
            ->nullable(),
    ]);
}

```

Filament resolves whether it is rendering a form or an infolist and maps components accordingly. `TextInput` in a form context becomes a `TextEntry` in an infolist context unless you override it explicitly.

---

Explicit Infolist Overrides
---------------------------

Automatic mapping covers the common cases, but you will sometimes need a richer read-only presentation. Use `->infolistComponent()` on any schema component to swap it out:

```php
use Filament\Infolists\Components\ImageEntry;

TextInput::make('avatar_url')
    ->label('Avatar URL')
    ->url()
    ->infolistComponent(
        ImageEntry::make('avatar_url')->circular()
    ),

```

The form still renders a URL input; the infolist renders a circular image. One definition, two presentations.

---

Extracting Reusable Schema Fragments
------------------------------------

The real productivity gain is extracting shared fragments into plain classes:

```php
namespace App\Filament\Schemas;

use Filament\Forms\Components\Section;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Textarea;

final class AuthorSchema
{
    public static function components(): array
    {
        return [
            Section::make('Author')
                ->columns(2)
                ->schema([
                    TextInput::make('author_name')->required(),
                    Textarea::make('author_bio')->columnSpanFull(),
                ]),
        ];
    }
}

```

Then spread it into any resource schema:

```php
return $schema->components([
    ...AuthorSchema::components(),
    TextInput::make('title')->required(),
]);

```

No trait magic, no inheritance — just plain PHP arrays.

---

Conditional Visibility Without Duplication
------------------------------------------

Schema components carry `->visibleOn()` and `->hiddenOn()` helpers that accept context strings (`'form'`, `'infolist'`, or custom panel identifiers):

```php
TextInput::make('internal_notes')
    ->hiddenOn('infolist'),

TextEntry::make('audit_log')
    ->visibleOn('infolist'),

```

This lets you keep a single schema while still surfacing fields that only make sense in one context.

---

Testing the Unified Schema
--------------------------

Pest assertions work against the resolved context. Use `livewire()` to target the specific page class:

```php
use App\Filament\Resources\PostResource\Pages\EditPost;

it('validates required fields on edit', function () {
    $post = Post::factory()->create();

    livewire(EditPost::class, ['record' => $post->getRouteKey()])
        ->fillForm(['title' => ''])
        ->call('save')
        ->assertHasFormErrors(['title' => 'required']);
});

```

For infolist assertions, target the `ViewPost` page and assert entries are visible:

```php
use App\Filament\Resources\PostResource\Pages\ViewPost;

it('shows author name in infolist', function () {
    $post = Post::factory()->create(['author_name' => 'Ada Lovelace']);

    livewire(ViewPost::class, ['record' => $post->getRouteKey()])
        ->assertSeeText('Ada Lovelace');
});

```

---

Key Takeaways
-------------

- **One schema, two contexts**: v4's unified Schema API eliminates the form/infolist duplication that plagued v3 resources.
- **Automatic component mapping** handles the common cases; `->infolistComponent()` handles the rest.
- **Fragment classes** are the idiomatic way to share schema sections across resources — no traits needed.
- **`->visibleOn()` / `->hiddenOn()`** give per-context visibility without splitting the schema.
- **Pest tests** target page classes directly; form and infolist assertions remain distinct even though the schema is shared.

 Found this useful?

          [  ](https://twitter.com/intent/tweet?url=https%3A%2F%2Fmsaied.com%2Farticles%2Ffilament-v4-schema-based-forms-infolists-and-the-unified-schema-api-4&text=Filament+v4+Schema-Based+Forms%2C+Infolists%2C+and+the+Unified+Schema+API) [  ](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fmsaied.com%2Farticles%2Ffilament-v4-schema-based-forms-infolists-and-the-unified-schema-api-4) 

 Frequently Asked Questions 
----------------------------

  3 questions  

     Q01  Does the unified Schema API mean I can no longer customise the infolist independently?        No. You can still override individual components with `-&gt;infolistComponent()` and control visibility per context with `-&gt;visibleOn()` / `-&gt;hiddenOn()`. The unified API reduces duplication for the common case while preserving full control when you need it. 

      Q02  Are Filament v3 form and infolist definitions still valid in v4?        Filament v4 ships compatibility shims for the separate `form()` and `infolist()` methods, but they are deprecated. The recommended migration path is to consolidate into a single `schema()` method and use context helpers for any divergence. 

      Q03  How do I share a schema fragment between a CreatePost and EditPost page?        Extract the shared components into a static method on a plain PHP class (e.g. `PostSchema::components()`) and spread the array into each resource's `schema()` call. No base class or trait is required. 

  Continue reading

 More Articles 
---------------

 [ View all    ](https://msaied.com/articles) 

 [ ![PhpStorm 2026.2 Released: Laravel Tool Window, PHP 8.5 Pipe Operator, and AI Agents](https://cdn.msaied.com/505/151a0bba66cc27064e090e69e55d7c92.png) PhpStorm JetBrains PHP 8.5 

### PhpStorm 2026.2 Released: Laravel Tool Window, PHP 8.5 Pipe Operator, and AI Agents

PhpStorm 2026.2 ships a dedicated Laravel tool window with Artisan, error logs, and Laravel Cloud tabs, plus P...

  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said 

 3 Aug 2026     3 min read  

  Read    

 ](https://msaied.com/articles/phpstorm-20262-released-laravel-tool-window-php-85-pipe-operator-and-ai-agents) [ ![Laravel Doctor: Diagnose Your Laravel App With One Artisan Command](https://cdn.msaied.com/504/d72224689abc7b396bce187535008272.png) Laravel Artisan Health Checks 

### Laravel Doctor: Diagnose Your Laravel App With One Artisan Command

Laravel Doctor is a first-party package announced at Laracon US 2026 that adds an `artisan doctor` command to...

  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said 

 3 Aug 2026     4 min read  

  Read    

 ](https://msaied.com/articles/laravel-doctor-diagnose-your-laravel-app-with-one-artisan-command) [ ![Livewire v4.3.5 Released: Fix for SFC Detection with PHP Attribute Array Arguments](https://cdn.msaied.com/503/9678ed8dbf5d7a6f4f19ca7694cf241b.png) Livewire Laravel PHP 

### Livewire v4.3.5 Released: Fix for SFC Detection with PHP Attribute Array Arguments

Livewire v4.3.5 ships a targeted bug fix for Single File Component (SFC) detection when PHP attributes contain...

  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said 

 3 Aug 2026     2 min read  

  Read    

 ](https://msaied.com/articles/livewire-v435-released-fix-for-sfc-detection-with-php-attribute-array-arguments) 

   [  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png)   Mohamed Said Laravel Backend Engineer  ](https://msaied.com)Senior Backend Engineer specializing in Laravel, scalable SaaS platforms, APIs, and cloud infrastructure. I build secure, high-performance web applications that help businesses grow.

Explore

- [Home](https://msaied.com)
- [Projects](https://msaied.com/projects)
- [Articles](https://msaied.com/articles)
- [Certificates](https://msaied.com/certificates)
- [Contact](https://msaied.com#contact-section)

Connect

- [   hello@msaied.com ](mailto:hello@msaied.com)
- [   +20 109 461 9204 ](tel:+201094619204)

© 2026 Mohamed Said. All rights reserved.

 [  ](https://github.com/EG-Mohamed) [  ](https://www.linkedin.com/in/msaiedm/) [  ](https://wa.me/201094619204) [  ](mailto:hello@msaied.com) [  ](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)
