FilamentPHP is a fantastic package which uses Livewire and cleverness to make quick and effective admin panels.
My development environment is Laravel Sail, with Octane configured to use Frankenphp as the application server.
The default theme and environment of Filament doesn't have HMR and doesn't run through Vite. Custom themes? Yep. This? Nope.
So I wanted a simple way of getting my page refreshed automatically.
As I mentioned above, I am using Frankenphp. The feature of Frankenphp I am relying on here is that the application is bootstrapped, once, with a set number of workers, and a cap on requests, when it's recycled and replaced with a fresh bootstrapped application, instead of bootstrapping each and every single page refresh. This means when the app boots, if I generate a timestamp and store it somewhere accessible, it won't change until the worker refreshes, no matter how many times the page refreshes.
Using an AppService provider, when the app boots a timestamp is generated and temporarily stored in a config key.
A client Javascript is added to the Filament renderHook::SCRIPTS_BEFORE
to poll this every 3 seconds, store the timestamp in the browser, and refresh the page when either the poll notes the timestamp changed or on error. You can make that more or less frequent as suits your needs.
This also (unfortunately) means that a GET /app-boot appears in the STDOUT logs so I change the logging level to hide them as they aren't of use to me anyway. And further, if you use barryvdh/laravel-debugbar it's going to fill that with useless logs, unless you disable it for the route too, so I did.
I am very, very early in the dev stages with this app. It doesn't have Redis, no Pusher, no Broadcasts/Notifications, no Events, no Server Sent Events. In following best practice I should have put the script in a blade or js file and sent it that way. But I wanted a one-page super-simple script to fit the job I need it to do now.
As I build up the app, I will either not need it anymore and remove it, or I will replace it with a solution which follows best practice. In the meantime, my pages refresh :)
- Add a config key somewhere to your app, I placed it in config/app.php
'boot' => '',
-
Add the AppBootServiceProvider to app/Providers.
-
Add
$this->app->register(AppBootServiceProvider::class);
to yourAppServiceProvider->register()
method -
Edit your docker-compose or .env to make sure the supervisor command limits workers to 1 and changes the log-level to stop sending http access logs.
SUPERVISOR_PHP_COMMAND: "/usr/bin/php -d variables_order=EGPCS /app/artisan octane:start --workers=1 --max-requests=300 --watch --poll --server=frankenphp --admin-port=2019 --port=443 --host=localhost --http-redirect --https --log-level=warn"
2025-02-13: Added \Debugbar::disable();
to ServiceProvider to prevent debugbar logging this URI and filling logs
2025-02-11: Release