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: Practical Patterns for the Unified Schema API        On this page       1. [  Why the Schema API Exists ](#why-the-schema-api-exists)
2. [  The New Method Signatures ](#the-new-method-signatures)
3. [  Reusable Schema Components ](#reusable-schema-components)
4. [  Conditional Rendering Without Duplication ](#conditional-rendering-without-duplication)
5. [  Gotchas to Watch For ](#gotchas-to-watch-for)
6. [  Key Takeaways ](#key-takeaways)

  ![Filament v4 Schema-Based Forms: Practical Patterns for the Unified Schema API](https://cdn.msaied.com/525/44fb6fe80b4b2439c1b1d9124976c67d.png)

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

 Filament v4 Schema-Based Forms: Practical Patterns for the Unified Schema API 
===============================================================================

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

       Table of contents

1. [  01   Why the Schema API Exists  ](#why-the-schema-api-exists)
2. [  02   The New Method Signatures  ](#the-new-method-signatures)
3. [  03   Reusable Schema Components  ](#reusable-schema-components)
4. [  04   Conditional Rendering Without Duplication  ](#conditional-rendering-without-duplication)
5. [  05   Gotchas to Watch For  ](#gotchas-to-watch-for)
6. [  06   Key Takeaways  ](#key-takeaways)

 Why the Schema API Exists
-------------------------

In Filament v3 you maintained two parallel trees: `form(Form $form)` returned a `Form` wrapping `Components\*`, and `infolist(Infolist $infolist)` returned an `Infolist` wrapping `Entries\*`. The same field — say, a user's email — needed two separate definitions that drifted apart over time.

Filament v4 collapses this into a **unified Schema**. One component tree can render as an editable form *or* a read-only infolist depending on context. The practical payoff is a single source of truth for layout, validation hints, and conditional visibility.

---

The New Method Signatures
-------------------------

```php
use Filament\Resources\Resource;
use Filament\Schemas\Schema;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Select;
use Filament\Infolists\Components\TextEntry;

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

            TextInput::make('email')
                ->email()
                ->required(),

            Select::make('role')
                ->options(Role::class)
                ->required(),
        ]);
    }
}

```

The `form()` and `infolist()` overrides still exist for cases where you need divergent layouts, but the default resolution delegates to `schema()`. If you only override `schema()`, Filament renders form inputs on edit pages and text entries on view pages automatically.

---

Reusable Schema Components
--------------------------

The real power emerges when you extract shared layouts into dedicated classes:

```php
namespace App\Filament\Schemas;

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

class AuditSchema
{
    public static function components(): array
    {
        return [
            Section::make('Audit')
                ->collapsed()
                ->schema([
                    TextInput::make('created_by')->disabled(),
                    DateTimePicker::make('created_at')->disabled(),
                    DateTimePicker::make('updated_at')->disabled(),
                ]),
        ];
    }
}

```

Then compose it anywhere:

```php
public static function schema(Schema $schema): Schema
{
    return $schema->components([
        // ... resource-specific fields
        ...AuditSchema::components(),
    ]);
}

```

This pattern replaces the v3 habit of duplicating `Section` blocks across `form()` and `infolist()` with slightly different entry types.

---

Conditional Rendering Without Duplication
-----------------------------------------

A common v3 pain point was toggling visibility differently between form and infolist. In v4 you can inspect the schema's context:

```php
use Filament\Schemas\Schema;
use Filament\Forms\Components\Textarea;

Textarea::make('notes')
    ->visible(fn (Schema $livewire) => ! $livewire->isReadOnly()),

```

The `isReadOnly()` helper returns `true` when the schema is rendering as an infolist, letting you hide fields that make no sense in a read context without maintaining two trees.

---

Gotchas to Watch For
--------------------

**Validation rules still live on form components.** When a `TextInput` renders as a text entry, its `->required()` and `->rules()` calls are silently ignored — they don't bleed into infolist rendering. This is correct behaviour, but it means you should not rely on schema-level validation for display logic.

**Custom entry types need explicit registration.** If you built a custom `Infolist\Components\MoneyEntry` in v3, it won't automatically map from a `MoneyInput` form component. You must either extend the new `Component` base class or keep the explicit `infolist()` override for that resource.

**Livewire state keys are unchanged.** The schema API is a rendering abstraction; the underlying Livewire component state and `$data` array behave identically to v3.

---

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

- Define `schema()` once; Filament resolves form vs. infolist rendering automatically.
- Extract shared layout blocks into plain PHP classes returning `array` — no base class needed.
- Use `isReadOnly()` for context-aware visibility instead of duplicating components.
- Custom v3 entry types require explicit porting; they don't auto-map from form components.
- `form()` and `infolist()` overrides remain valid escape hatches for genuinely divergent layouts.

 Found this useful?

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

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

  3 questions  

     Q01  Can I still override form() and infolist() separately in Filament v4?        Yes. The schema() method is the new default, but form() and infolist() overrides take precedence when defined. Use them when your edit and view layouts genuinely differ enough to warrant separate trees. 

      Q02  Do validation rules on TextInput affect infolist rendering in v4?        No. Validation rules such as required() and rules() are only applied when the schema renders as an editable form. They are ignored during infolist (read-only) rendering, so there is no risk of spurious validation errors on view pages. 

      Q03  How do I migrate a large v3 resource with both form() and infolist() to the v4 schema() approach?        Start by identifying fields that are identical in both methods and move them into schema(). Keep form() and infolist() only for the divergent parts. Gradually reduce those overrides as you consolidate, using isReadOnly() for any remaining conditional differences. 

  Continue reading

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

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

 [ ![PostgreSQL JSONB in Laravel: Indexing, Querying, and Casting Without the Chaos](https://cdn.msaied.com/526/bc43aae3afe723f9a29f47820735edf5.png) laravel postgresql jsonb 

### PostgreSQL JSONB in Laravel: Indexing, Querying, and Casting Without the Chaos

JSONB columns unlock flexible schemas, but without the right indexes and Eloquent integration they become a pe...

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

 9 Aug 2026     3 min read  

  Read    

 ](https://msaied.com/articles/postgresql-jsonb-in-laravel-indexing-querying-and-casting-without-the-chaos-2) [ ![Laravel Pipeline Pattern: Building Custom Pipelines Beyond Middleware](https://cdn.msaied.com/524/bffe5038d4150b93f86c783df9f73d28.png) laravel design-patterns architecture 

### Laravel Pipeline Pattern: Building Custom Pipelines Beyond Middleware

The Pipeline pattern in Laravel is far more powerful than middleware alone. Learn how to compose reusable, tes...

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

 8 Aug 2026     3 min read  

  Read    

 ](https://msaied.com/articles/laravel-pipeline-pattern-building-custom-pipelines-beyond-middleware-3) [ ![Eloquent Query Optimization: Slaying N+1 Problems at Scale](https://cdn.msaied.com/523/a12bd8c82544aafcd6de50ff8c076141.png) laravel eloquent performance 

### Eloquent Query Optimization: Slaying N+1 Problems at Scale

N+1 queries silently kill Laravel app performance. This guide digs into eager loading strategies, query dedupl...

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

 8 Aug 2026     4 min read  

  Read    

 ](https://msaied.com/articles/eloquent-query-optimization-slaying-n1-problems-at-scale) 

   [  ![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)
