awcodes/filament-sticky-header
Filament Panel plugin that makes page headers sticky while scrolling. Install via Composer, import the plugin CSS into your custom theme, then register StickyHeaderPlugin in your panel provider. Includes optional Floating theme and colored header styling.
composer require awcodes/filament-sticky-header
@import '../../../../vendor/awcodes/filament-sticky-header/resources/css/plugin.css';
PanelProvider:
use Awcodes\StickyHeader\StickyHeaderPlugin;
public function panel(Panel $panel): Panel {
return $panel
->plugins([
StickyHeaderPlugin::make(),
]);
}
Enable sticky headers for all pages in your Filament panel. The plugin automatically applies to resource pages (e.g., PostsTable, PostsCreateEditPage) and custom pages.
Default Behavior:
Conditional Activation:
floating() for a detached, floating header:
StickyHeaderPlugin::make()->floating()
colored():
StickyHeaderPlugin::make()->floating()->colored()
StickyHeaderPlugin::make()
->floating(fn () => auth()->user()->prefers_floating_header)
Exclusions:
stickOnListPages(false):
StickyHeaderPlugin::make()->stickOnListPages(false)
StickyHeaderPlugin::make()->disabledOn([
App\Filament\Pages\MyCustomPage::class,
])
Or dynamically:
StickyHeaderPlugin::make()->disabledOn(fn () => [
auth()->user()->is_admin ? AdminDashboard::class : [],
])
Integration with Filament Features:
wire:navigated events)..filament-sticky-header {
/* Custom styles */
}
sticky-header:stick, sticky-header:unstick). Use Alpine.js or Livewire hooks:
document.addEventListener('sticky-header:stick', () => {
console.log('Header stuck!');
});
Missing Custom Theme:
CSS Conflicts:
.filament-sticky-header {
z-index: 50; /* Higher than Filament's top bar */
}
JavaScript Scope:
Performance:
floating() theme for smoother transitions, as it decouples from scroll events.Uncaught TypeError if the plugin fails to load. Ensure the CSS import path is correct..filament-sticky-header class is applied to the correct element..filament-sticky-header.transitioning {
transition: transform 0.3s ease;
}
disabledOn closure to exclude pages based on user roles, permissions, or other runtime conditions:
->disabledOn(fn () => [
auth()->user()->cannot('view-dashboard') ? Dashboard::class : [],
])
window.addEventListener('alpine:init', () => {
Alpine.data('stickyHeader', () => ({
init() {
this.$watch('scroll', (value) => {
console.log('Scroll position:', value);
});
}
}));
});
filament-notifications or filament-spinners for a polished UX. The plugin handles z-index conflicts out of the box.floating() and colored() closures to test different header styles with users:
->floating(fn () => request()->query('theme') === 'floating')
How can I help you explore Laravel packages today?