Filament v4 Unified Schema API: Forms &amp; Infolists | Mohamed Said       [Skip to content](#main)  [ ![](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png) Mohamed SaidLaravel Backend Engineer ](https://msaied.com/public) - [Home](https://msaied.com/public)
- [Projects](https://msaied.com/public/projects)
- [Articles](https://msaied.com/public/articles)
- [Certificates](https://msaied.com/public/certificates)
- [About](https://msaied.com/public#about)

           [  Contact](https://msaied.com/public#contact) Menu 

Menu
----

Close 

 - [HomeStart here](https://msaied.com/public)
- [ProjectsCase studies](https://msaied.com/public/projects)
- [ArticlesEngineering notes](https://msaied.com/public/articles)
- [CertificatesCredentials](https://msaied.com/public/certificates)
- [AboutHow I work](https://msaied.com/public#about)
- [ContactGet in touch](https://msaied.com/public#contact)

  [Start a conversation](https://msaied.com/public#contact) [WhatsApp](https://wa.me/201094619204) [Email](mailto:hello@msaied.com) 

 1. [Home](https://msaied.com/public)
2. /
3. [Articles](https://msaied.com/public/articles)
4. /
5. Filament v4 Schema-Based Forms: Practical Patterns for the Unified Schema API

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

 Filament v4 replaces scattered form/infolist definitions with a single Schema API. This post walks through real migration patterns, reusable schema components, and the gotchas that will bite you first.

 ![](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp) [Mohamed Said](https://msaied.com/public#person) Published 8 Aug 2026 · Updated 8 Aug 2026 · 3 min read

ShareCopy linkCopied

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

  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)

 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.

- [filament](https://msaied.com/public/articles?search=filament)
- [laravel](https://msaied.com/public/articles?search=laravel)
- [filament-v4](https://msaied.com/public/articles?search=filament-v4)
- [admin-panels](https://msaied.com/public/articles?search=admin-panels)

 Frequently asked questions 
---------------------------

  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.

   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.

   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.

   ![Mohamed Said](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp)About the author
----------------

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

[About](https://msaied.com/public#about) [GitHub ↗](https://github.com/EG-Mohamed) [LinkedIn ↗](https://www.linkedin.com/in/msaiedm/) [WhatsApp ↗](https://wa.me/201094619204) [Email Address ↗](mailto:hello@msaied.com) [My CV ↗](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)  

   [Previous articleLaravel Pipeline Pattern: Building Custom Pipelines Beyond Middleware](https://msaied.com/public/articles/laravel-pipeline-pattern-building-custom-pipelines-beyond-middleware-3) [Next articlePostgreSQL JSONB in Laravel: Indexing, Querying, and Casting Without the Chaos](https://msaied.com/public/articles/postgresql-jsonb-in-laravel-indexing-querying-and-casting-without-the-chaos-2)  

   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)

 ###  Have a technical challenge?

 Tell me what you’re building. I reply within two working days.

[Start a conversation](https://msaied.com/public#contact) 

   Related articles
-----------------

 [ ![](https://cdn.msaied.com/745/8744e1be5136b430da52e9fca3ed3964.png)  · 3 min read### Service Container Deep Dive: Contextual Binding, Tagging, and Method Injection

6 Oct 2026 ](https://msaied.com/public/articles/service-container-deep-dive-contextual-binding-tagging-and-method-injection-1) [ ![](https://cdn.msaied.com/743/8998fac3a41451ab3fe1588194e17a43.png) Filament · 3 min read### Securing Filament Plugins with Plumb: Automated Security Scoring for PHP Packages

5 Oct 2026 ](https://msaied.com/public/articles/securing-filament-plugins-with-plumb-automated-security-scoring-for-php-packages) [ ![](https://cdn.msaied.com/742/2d02018669cdeedccb5de2efb898f0ee.png) Filament · 3 min read### Filament v3.3.56 Released: File Hash Names and Livewire Upload Fix

5 Oct 2026 ](https://msaied.com/public/articles/filament-v3356-released-file-hash-names-and-livewire-upload-fix) 

  Have a technical challenge?
----------------------------

Tell me what you’re building. I reply within two working days.

 [Discuss your project ↗](https://msaied.com/public#contact) 

  © 2026 Mohamed Said · Built with Laravel, meant to last.Senior Backend Engineer specializing in Laravel, scalable SaaS platforms, APIs, and cloud infrastructure. I build secure, high-performance web applications that help businesses grow.

 - [Home](https://msaied.com/public)
- [Articles](https://msaied.com/public/articles)
- [Certificates](https://msaied.com/public/certificates)
- [GitHub](https://github.com/EG-Mohamed)
- [LinkedIn](https://www.linkedin.com/in/msaiedm/)
- [WhatsApp](https://wa.me/201094619204)
- [Email Address](mailto:hello@msaied.com)
- [My CV](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)
- [Sitemap](https://msaied.com/public/sitemap.xml)
