Changelog
All notable changes to this project will be documented in this file.
[v2.0.0] - 2026-03-28
A full rewrite targeting Filament v4 and v5. The architecture has been overhauled
for long-term stability - actions no longer depend on internal Filament hooks and
work out of the box without any trait on the page class.
Added
-
NavigationPageenum (View,Edit) - controls which Filament page type
an action navigates to. Pass it via->navigateTo(NavigationPage::Edit)on
either action. Each action can target a different page type independently. -
HasRecordNavigationcontract (src/Contracts/HasRecordNavigation.php) -
optional interface for page classes that want strict typing, IDE autocompletion,
or static analysis support (PHPStan / Psalm). DeclaresgetPreviousRecord(),
getNextRecord(), andgetRecordNavigationUrl(). -
ResolvesAdjacentRecordtrait (src/Actions/Concerns/ResolvesAdjacentRecord.php) -
internal trait shared by both actions. Owns the per-render query cache,
URL resolution logic, and the config-driven fallback query. Eliminates the
duplicateddefaultAdjacentQuery()method that previously existed in both
action classes. -
Per-render query cache in
ResolvesAdjacentRecord::getCachedRecord()-
each action previously fired 3 separate database queries per render (one each
forcolor(),disabled(), andurl()). The cache reduces this to 1 query
per action per render, keyed by direction andspl_object_id($livewire). -
$livewireinjection architecture - actions resolve the current record
and URL entirely through Filament's official$livewireutility injection
parameter. No internal Filament lifecycle hooks (configureAction()etc.) are
used anywhere, making the package resilient to future Filament upgrades.
Changed
-
Breaking - Filament version: minimum supported version is now
^4.0|^5.0
(was^3.0). PHP minimum is^8.2(was^8.1). -
Breaking - trait is now optional:
WithRecordNavigationno longer needs
to be added to every page.PreviousRecordActionandNextRecordActionwork
without it using a config-driven fallback query. Add the trait only when you
need to overridegetPreviousRecord(),getNextRecord(), or
getRecordNavigationUrl(). -
Breaking - method renamed:
getRecordUrl(Model $record)has been renamed
togetRecordNavigationUrl(Model $record, NavigationPage $page). The second
parameter allows the method to know which page type the action is targeting
and build the correct URL accordingly. -
Breaking -
configureAction()removed: the v1 trait hooked into
Filament's internalconfigureAction()method to wire up the record query
and URL. This hook is not part of Filament's public API and is not guaranteed
to be stable across versions. It has been removed entirely - wiring now happens
inside the actions themselves via$livewireinjection. -
method_exists()replacesinstanceof: actions now check for navigation
methods usingmethod_exists($livewire, 'getPreviousRecord')instead of
$livewire instanceof HasRecordNavigation. PHP traits do not satisfy
instanceofchecks - the class must explicitly declareimplementsfor that
to work.method_exists()correctly detects the method regardless of how it
was added (trait, direct definition, or interface implementation). -
getRecordNavigationUrlreplacesgetNavigationUrl: the method was
renamed fromgetNavigationUrltogetRecordNavigationUrlbecause
Filament's basePageclass already declares a staticgetNavigationUrl()
method (used for sidebar navigation). Declaring the same name as non-static
in a trait caused a fatal PHP error. -
Default button style: actions now call
->button()->outlined()explicitly.
In Filament v5,->outlined()alone does not render correctly without
->button()being called first.
Fixed
-
Fatal error on page load (
Cannot make static method Page::getNavigationUrl() non static) - caused by a method name collision with Filament's own
getNavigationUrl()static method on the basePageclass. Fixed by
renaming togetRecordNavigationUrl()throughout. -
Custom filter overrides silently ignored -
getPreviousRecord()and
getNextRecord()overrides on the page class were never called because the
instanceof HasRecordNavigationcheck always returnedfalsewhen the
interface was not explicitly declared. Fixed by switching tomethod_exists(). -
3× redundant database queries per action per render -
color(),
disabled(), andurl()each independently called the record resolution
method, resulting in 3 queries per action (6 per page render). Fixed by
introducinggetCachedRecord()inResolvesAdjacentRecord.
Removed
-
Facade (
FilamentRecordNav) - was registered in v1 but never provided
any functionality. Removed to keep the package lean. -
configureAction()hook - removed fromWithRecordNavigation. See
"Changed" above for the rationale.
[v1.0.0] - 2025-05-27
Initial stable release targeting Filament v3.
Added
NextRecordAction- Filament header action to navigate to the next recordPreviousRecordAction- Filament header action to navigate to the previous recordWithRecordNavigationtrait - wires actions to the page viaconfigureAction()config/filament-record-nav.php- configurableorder_columnand sort directions