Search by

mortalkiller / filament-page-header

pedro.monteiro.ps@gmail.com

Opt-in, schema-based Filament page headers with responsive sticky and compact modes.

Package info

github.com/mortalkiller/filament-page-header

pkg:composer/mortalkiller/filament-page-header

Fund package maintenance!

buymeacoffee.com/mortalkiller

Statistics

Installs: 1 489

Dependents: 2

Suggesters: 0

Stars: 10

Open Issues: 0

v2.4.3 2026-09-22 09:24 UTC

README

Filament Page Header showcase

Filament Page Header

Latest version Total downloads Package tests License

Scanned by Plumb Plumb ecosystem score Plumb maintenance score Plumb security score Plumb score

Build informative, responsive page headers with native Filament 4 and 5 schemas. Combine identity, status, metadata and page actions, then choose what stays visible while scrolling.

Enable headers only on the panels and pages you choose. No custom theme build, application-specific models or required icon library.

Why

Filament's native page headers are intentionally simple, which is often exactly what an application needs. The friction starts when several pages need richer identity, status, metadata, responsive actions, sticky behavior or compact-on-scroll presentation. Reimplementing that per Resource usually means repeated Blade overrides, layout CSS and interaction code that can drift away from Filament's native actions and navigation.

Filament Page Header exists to keep that richer presentation inside Filament's schema system. It provides one reusable, opt-in composition layer while leaving records, authorization, actions, breadcrumbs and sub-navigation under Filament's control. Pages that do not need a richer header can keep the native header unchanged.

Documentation

Full documentation, guides and API reference:

https://docs.pedromonteiro.dev/filament-page-header/

Contents

Features

  • Headings, descriptions, badges, avatars, initials and product images.
  • Native schema fields for metadata and summary metrics, with responsive separators.
  • Field icons before or after the complete label/value, with configurable size.
  • Native page actions with Start, End and Below positions and a full-width mobile layout.
  • Breadcrumb positioning and optional native page/record sub-navigation inside the header.
  • Normal, sticky and compact layouts, with configurable responsive thresholds.
  • Typed compact configuration: keep entire blocks, select fields, or include/exclude native actions by name.
  • Native light/dark colors, keyboard focus handling and reduced-motion support.
  • Shared resource schemas, with individual page overrides.
  • Artisan generator for conventional header schemas and Resource page setup.

Screenshots

Real captures of the package's product demo: a product image, two actions and three information fields. The example uses fictional product data, English labels and a native indigo/gray palette. The product image and banner are illustrative assets; the header itself is rendered by Filament. Native action colors follow your panel configuration.

Layout Light Dark
Desktop Expanded desktop product header in light mode Expanded desktop product header in dark mode
Compact after scrolling Compact desktop product header in light mode Compact desktop product header in dark mode
Mobile Mobile product header in light mode Mobile product header in dark mode

Run the demo locally to explore the layouts and native actions.

Version compatibility

This README documents 2.x. Package major versions identify this package's API; they do not correspond to Filament major versions.

Package version Filament requirement PHP requirement Laravel API
^2.0 ^4.12.6 || ^5.8.1 ^8.3 12 or 13 Header, MetadataEntry, typed compact configuration
^1.0 ^5.8.1 ^8.3 12 or 13 Previous HeaderLayout API

Version 2 runs its PHP suite against the minimum secure Filament 4 release (4.12.6), the latest release resolved by ^4.12.6, the minimum Filament 5 release (5.8.1) and the latest release resolved by ^5.8.1, across Laravel 12 and 13, including PHP 8.5 on the latest dependency boundaries. The Chromium suite runs on the minimum supported Filament 4 release and the latest release resolved by ^5.8.1. Versions before 4.12.6 are outside the declared requirement; Composer specifically blocks 4.0.0 and 4.12.04.12.5 because of known security advisories. Filament 5.05.8.0 is also outside the declared requirement and has not been validated. Other Filament majors are outside these releases' requirements. PHP must also satisfy your selected Laravel version's requirements.

See the 1.x README for the previous API and the verification record for executed checks. Security maintenance is documented separately in the security policy.

Installation

1. Install the package

composer require mortalkiller/filament-page-header:^2.0

2. Publish Filament assets

php artisan filament:assets

The service provider is discovered automatically. There are no package migrations to run and no custom theme build is required.

3. Register the plugin

Add the plugin to the intended panel's existing configuration:

use MortalKiller\FilamentPageHeader\PageHeaderPlugin;

$panel->plugin(PageHeaderPlugin::make());

Register it separately for each panel that needs custom headers, then add the page trait as shown below. Installation alone does not replace existing headers.

Generator

For an existing Filament Resource, generate the conventional header schema and choose which standard Resource pages should use it:

php artisan make:filament-page-header OrderResource

For explicit or non-interactive usage:

php artisan make:filament-page-header OrderResource \\
    --panel=admin \\
    --page=list \\
    --page=view \\
    --page=edit

Use --no-pages to generate only the schema and --force to deliberately replace an existing generated schema. Repeated runs do not duplicate HasPageHeader imports or trait declarations.

See the generator guide for page selection, multi-panel applications, existing schemas and supported page types.

Your first header

For an existing CustomerResource, add HasPageHeader and headerSchema() to its Edit page. This example assumes the model has name and email attributes; retain your page's existing methods and actions.

<?php

namespace App\Filament\Resources\Customers\Pages;

use App\Filament\Resources\Customers\CustomerResource;
use Filament\Resources\Pages\EditRecord;
use Filament\Schemas\Schema;
use Illuminate\Database\Eloquent\Model;
use MortalKiller\FilamentPageHeader\Components\Header;
use MortalKiller\FilamentPageHeader\Concerns\HasPageHeader;

class EditCustomer extends EditRecord
{
    use HasPageHeader;

    protected static string $resource = CustomerResource::class;

    public function headerSchema(Schema $schema): Schema
    {
        return $schema->components([
            Header::make()
                ->heading(fn (Model $record) => $record->getAttribute('name'))
                ->description(fn (Model $record) => $record->getAttribute('email'))
                ->initials(fn (Model $record) => $record->getAttribute('name')),
        ]);
    }
}

The trait also works with Create, View, List and custom pages. Use nullable record closures where no record exists. Header::make() inherits the page heading and subheading by default and does not change the browser tab title. By default, the header schema uses the page's current Resource record; override getPageHeaderRecord() for tenant, parent, singleton, custom-model or array-backed contexts.

Configuration

Use native Filament entries for content and keep business logic in your application. The package handles layout, images, spacing and light/dark appearance.

Configure API Guide
Identity heading(), description(), avatar(), image(), initials(), icon(), initialsBgColor(), initialsTextColor(), iconBgColor(), iconColor() Images and icons
Badges and details badges(), metadata(), summary() Layout slots
Native actions actionsPosition(), compact actions() / hideActions() Native action control
Field icons fieldIcon(), fieldIconPosition(), fieldIconSize() Metadata fields
Product identity image() and descriptionSchema() Product example
Reusable resource headers Convention discovery or schemaFor() Shared configuration
Record/context getPageHeaderRecord() Custom record contexts
Custom composition headingSchema(), leading(), schema() Layout slots

Native getHeaderActions() continues to define the page actions. They render once, at the logical end on desktop by default and after the details on mobile. Native button groups, modals, form targets and authorization remain in place. Breadcrumbs sit outside the card and scroll with the page by default. Configure their position and native sub-navigation when needed.

Color an initials fallback with a panel color alias or a native Filament palette. The text color is chosen for contrast unless you override it:

use Filament\Support\Colors\Color;
use Filament\Support\Icons\Heroicon;

Header::make()
    ->initials(fn (Model $record) => $record->name)
    ->initialsBgColor('primary');

Header::make()
    ->initials(fn (Model $record) => $record->name)
    ->initialsBgColor(Color::Blue)
    ->initialsTextColor(Color::Blue);

Header::make()
    ->icon(Heroicon::OutlinedUser)
    ->iconBgColor('primary')
    ->iconColor(Color::Blue);

See Images and icons for imports, closures and fallback behavior.

For a resilient identity, configure image, initials and an icon together. The header renders one visual in this order: custom leading() content, a resolved avatar/image, initials, then icon().

Native page actions

Position the action block and choose which native action names remain in compact mode:

use MortalKiller\FilamentPageHeader\CompactHeader;
use MortalKiller\FilamentPageHeader\Components\Header;
use MortalKiller\FilamentPageHeader\Enums\HeaderActionsPosition;

Header::make()
    ->actionsPosition(HeaderActionsPosition::Below)
    ->compact()
    ->whenCompact(fn (CompactHeader $compact) => $compact
        ->actions(['save', 'approve']));

The example assumes those actions already exist in the page's getHeaderActions(). Positions are Start, End (default), and Below. Mobile keeps the existing full-width action area.

Use hideActions(['delete', 'duplicate']) instead for exclusion. The last selection call wins. actions([]) hides all native actions in compact mode, while hideActions([]) keeps all. Without action configuration, existing headers retain every action allowed by Filament.

Selection preserves native order and nested groups, removes empty compact groups, and keeps render hooks and active interactions intact. It does not replace server-side authorization or filter normal/sticky presentation. Read the complete action guide, including teleported dropdowns, forms and focus handling.

Header navigation

Keep Filament's breadcrumbs outside the card (the default), place them inside, or hide them:

use MortalKiller\FilamentPageHeader\Components\Header;
use MortalKiller\FilamentPageHeader\Enums\BreadcrumbPosition;

Header::make()->breadcrumbs(BreadcrumbPosition::Outside);
Header::make()->breadcrumbs(BreadcrumbPosition::Inside);
Header::make()->breadcrumbs(BreadcrumbPosition::Hidden);

Move existing native Page/Resource sub-navigation into the header with subNavigation(). Desktop uses Filament's horizontal tabs; mobile uses its dropdown. URLs, authorization, active state and SPA navigation stay native. No navigation is created if the page has none.

use MortalKiller\FilamentPageHeader\CompactHeader;
use MortalKiller\FilamentPageHeader\Enums\HeaderPart;

Header::make()
    ->breadcrumbs(BreadcrumbPosition::Inside)
    ->subNavigation()
    ->compact()
    ->whenCompact(fn (CompactHeader $compact) => $compact
        ->show(HeaderPart::Breadcrumbs, HeaderPart::SubNavigation));

Inside breadcrumbs and sub-navigation hide when compact unless explicitly retained. Retained outside breadcrumbs remain outside the card but join the pinned header; otherwise they scroll with the page as before. Navigation supports show(), not only() field selection. Hidden and panel-level breadcrumb disabling remain authoritative.

subNavigation() integrates route navigation such as getRecordSubNavigation() and ManageRelatedRecords pages. Relation Manager tabs remain in the page content, including combined content tabs and their Before/After ordering. Without subNavigation(), Filament keeps its original Start/End/Top layout.

See Navigation configuration for details.

Sticky and compact modes

Set a default on the panel plugin:

PageHeaderPlugin::make(); // Scroll normally.
PageHeaderPlugin::make()->sticky(); // Keep the full header pinned.
PageHeaderPlugin::make()->compact(); // Compact when the header reaches the sticky edge.
PageHeaderPlugin::make()->sticky()->compactBelow(1024);

You can also call normal(), sticky() or compact() on an individual Header. Call compactBelow() after selecting the base mode; its threshold is exclusive.

By default, compact mode keeps the heading, image/avatar, badges and native page actions. Choose optional content explicitly with enums:

use MortalKiller\FilamentPageHeader\CompactHeader;
use MortalKiller\FilamentPageHeader\Components\Header;
use MortalKiller\FilamentPageHeader\Enums\HeaderPart;

Header::make()
    ->compact()
    ->whenCompact(fn (CompactHeader $compact) => $compact
        ->show(HeaderPart::Image, HeaderPart::Badges)
        ->only(HeaderPart::Metadata, ['reference']));

Use this on a header whose metadata includes reference. Each whenCompact() callback starts with no optional blocks selected. The heading always remains; native page actions remain unless you configure actions() or hideActions(). Native visibility and authorization still apply. Scrolling does not duplicate actions or send Livewire requests.

Full compact configuration, offsets and responsive rules.

Migration from v1

Version 2 replaces HeaderLayout with Header and introduces a new composition API. Update consuming schemas and publish the assets again when upgrading.

Follow the migration guide, including the deprecated compact methods. For unreleased development on 2.x, deliberately use 2.x-dev with the local path and symlink workflow; keep your application's global stability unchanged.

Troubleshooting

Symptom Check
The native header still appears Register the plugin on the active panel, add HasPageHeader to the page and return a non-empty schema. A page's own getHeader() method takes precedence.
Styling or scrolling behavior is outdated Run php artisan filament:assets in the consuming application after updating the package, then reload. A Composer symlink does not refresh published assets.
The header does not stick Enable sticky() or compact(). Check the real scroll container, short parent wrappers and ancestor overflow. Pinning is temporarily disabled when the header cannot fit the viewport.
whenCompact() has no visible effect Enable compact() on the header or plugin, then scroll to the sticky edge. The callback selects content; it does not activate compaction.
A selected compact field disappears Match its entry name or layout key, and check native visibility conditions. Selection covers direct fields, not nested descendants.
A selected compact action is missing Use its native action name, not its label. Check native visibility and authorization; selection never overrides them.

Advanced layout and offset configuration.

Testing and contributing

composer check
node --test tests/JavaScript/*.test.mjs
npm run test:browser

See demo and testing setup before running browser tests, and CONTRIBUTING for branch conventions, checks and pull requests. The package has an independent workbench and does not require a consuming application's database.

Changelog

See GitHub Releases for published versions and release notes.

Roadmap

See the project roadmap for planned improvements, along with the package's scope and design principles.

Security

Please report vulnerabilities privately using the process in SECURITY.md. Use GitHub Issues for ordinary bugs and feature requests.

Heading and description text are escaped by default. Enable html: true only for trusted markup prepared by your application. Native visibility is not an authorization boundary; keep permission checks on the server.

The Plumb badges display the latest external assessment, which may lag behind repository changes. They are not a security audit or a guarantee that the package has no vulnerabilities.

Support this project

If this package saves you time, consider supporting its development. Your support helps maintain the package and improve its documentation.

Buy Me a Coffee

Credits and license

Licensed under the MIT license.