vitisstudio/filament-header-schema
Build Filament page headers with a schema-based API. Compose titles, actions, breadcrumbs, and custom header content consistently across resources and custom pages, cutting boilerplate and keeping headers clean, reusable, and easy to maintain.
Architecture fit. This package fills a narrow but real gap in Filament's extension surface. Forms, tables, and infolists are already schema-driven; the page header is historically where teams fall back to Blade (renderHeader() overrides, custom views, getHeaderWidgets()). filament-header-schema closes that gap with headerSchema() plus a HeaderSection primitive (leading/main/trailing slots), so headers become declarative, reusable across resources and panels, and reviewable in the same idiom the team already uses. From a TPM view this is low-controversy: it extends an existing convention rather than inventing a parallel one, and it is additive — no resource, page, or panel-provider rewrites beyond registration. That is what makes it fundable as hygiene rather than as a feature. It is also a standardization decision more than a capability one: Filament can already render these headers, just inconsistently and with more boilerplate each time.
Integration feasibility. Low effort, small blast radius, and reversible page by page. There is no data layer, no migrations, no background work, no auth surface. The failure domain is a single rendered region on a page. Realistic effort for a competent Filament engineer: half a day to install and validate on staging, one to two days per page conversion including screenshot comparison at multiple container widths. The public API is a superset of behaviour Filament already exposes, so existing getHeaderActions() continue to work unchanged. This is the kind of package a TPM can approve without a design review or a security review, provided the supply-chain questions below are answered.
Technical risk. The dominant risk is supply chain, not engineering. Nine stars, zero dependents, a single maintainer, and a 1.x line mean there is no herd to absorb breakage ahead of you, and no downstream pressure forcing the package to track Filament releases.
.fi-* markup and spacing, exactly the layer Filament does not guarantee across minors.@container queries against a named fi-hs-header inline-size container. This is the right fix — window width is the wrong question when a sidebar is open — but raises the browser floor to roughly Chrome 105 / Safari 16 / Firefox 110. Fine for internal admin tooling; name it explicitly if any kiosk or locked-down-browser user base exists.HeaderSection's ->from() breakpoints remain media queries against the window while the actions row now answers the container. Two layout models in one header is a standing bug source, and the maintainer has deliberately deferred it.40rem and 64rem of container width from side-by-side to stacked with "no API changes" — correct, but it will re-open visual sign-off. Budget a visual QA pass per upgrade.Key questions to answer before committing.
composer.json or merely observed? Pin and test rather than trust.Net: a thoughtfully engineered, narrow DX package whose adoption profile argues for borrowing the pattern and pinning the artifact. Treat it as an accelerator, not infrastructure.
Stack fit. Assumes a Filament panel on a modern Laravel/PHP baseline, Tailwind-driven styling, and a browser fleet at or above the container-query floor. It composes cleanly with a schema-first panel — header schemas sit beside resource forms and infolists, and header actions keep routing through Filament's action API. It fits poorly if headers are genuinely bespoke (charts, maps, non-schema widgets) or if there is a strict no-third-party-CSS-in-admin policy, since the package injects .fi-hs-header-ctn and resets a Filament spacing variable.
Migration path. Incremental and reversible per page, which is the primary reason this is safe to trial. Start with one rich header — avatar, status badges, customer, price, dates — on a resource that already has a hand-built Blade partial. Keep the old partial in the branch until the new header has shipped for a sprint. Only after two or three conversions should you standardise house conventions (HeaderSection slot usage, action placement, badge vocabulary). Do not attempt a big-bang header rewrite across all resources; the package's value is consistency, and consistency is cheaper to achieve after the second conversion than before the first.
Compatibility. Pin the version explicitly and verify the Filament and Tailwind constraints in composer.json against the panel's actual versions. Two cosmetic notes for the v1.1.0 upgrade: there is one more wrapper element in the rendered header, so audit any CSS or tests that assert on header sibling position; and headers between 40rem and 64rem of container width now stack where they previously sat side by side, which will move pixels on already-laid-out pages. HeaderSection's ->from() breakpoints are still window-based, so mixed behaviour is expected until a later release. Confirm the browser floor for any non-standard user base before rollout.
Sequencing. (1) Spike on staging: install, register, convert a single page, screenshot at multiple container widths including an open sidebar and a split-pane layout. (2) Run a visual QA pass against the old Blade header at 40rem and 64rem boundaries. (3) Convert a second and third page, then write down the house conventions. (4) Decide vendor-versus-depend based on the maintainer cadence observed during the spike. (5) Add the package's visual QA to the upgrade checklist for Filament minor bumps. Each step is a day or less of engineering time, and any step can be abandoned without touching the data layer.
Maintenance. You are taking on ownership. Pin the version, read the source, and be prepared to vendor it if upstream goes quiet. The maintenance surface itself is small — one rendered region per page, no runtime services — but the coupling to Filament's .fi-* markup means a Filament minor can break layout without breaking tests. Budget a visual QA pass per Filament upgrade, not per package upgrade, because that is where the breakage will originate.
Support. There is no vendor SLA, no security-response process, and no downstream pressure forcing the package to stay current with Filament releases. Nine stars and zero dependents mean you are the reference implementation. Document an internal owner and an exit plan: reverting a schema-driven header to Blade is a rewrite of that region, so the exit cost is per-page, not a config flip. For a handful of pages that is acceptable; across twenty resources it is a project.
Scaling. Across resources and panels the package scales well — define once, reuse the same identity block in an internal-ops panel and a customer-facing admin panel. Runtime cost is negligible. The scaling limit is expressiveness, not throughput: once a header needs something the schema components do not expose, you are back in Blade with an extra layer to maintain. Treat the package as covering the five-or-six-fact header, not every header.
Failure modes. The realistic ones are: a Filament minor reshuffles header DOM or spacing and the package's CSS assumptions break; the host Tailwind build does not scan the package's Blade, so styles are missing in production but present in dev; a user on a browser below the container-query floor gets a degraded stacked layout; a layout regression appears between 40rem and 64rem of container width after an upgrade; or the maintainer stops releasing and a future Filament major leaves you stranded. All are detectable with a screenshot comparison step and a pinned version, which is why the QA pass is the operational control that matters.
Ramp-up. Low for a Filament-fluent engineer — the schema builder is already familiar, and headerSchema() reads like the forms and infolists they write daily. The new concepts are HeaderSection slot composition and the container-query layout behaviour. Half a day to first productive commit, a sprint to house conventions. Document the conventions once, because the second engineer to touch a header will otherwise re-invent the Blade partial the package was adopted to remove.
How can I help you explore Laravel packages today?