If you've worked with Filament forms before, you might be familiar with setting one form field's value based on another, like creating a slug from a title. But what about file uploads? Wouldn't it be great to automatically fetch and upload a file, for example a favicon based on a website URL, or another field? In this post, we'll explore how to do just that.
Are you a visual learner? Check out the video ⬇️
What are we building?
For a Filament app, I needed to automatically fetch the favicon from the URL and show it in the form as a file upload. The user should have the opportunity to upload another image, if the favicon wasn't found or not suitable.
The Challenge
Files are different from other form field values. You can't simple use afterStateUpdated
with Set
to add a file to an upload field in Filament. You can upload it in the background and attach it to the form state, but that will not show the uploaded file preview in the form.
Using FilePond, Alpine.js and Livewire
After a brief discussion with Stefan Zweifel, a Laravel developer here in Switzerland and a magician with GitHub Actions, I was on the right path.
His suggestion was to download the image, create a base64 version of it and sending it to the FilePond API by dispatching an event in Livewire and catching it with Alpine.js. This almost worked, but Livewire had troubles understanding the mime type of the file.
How does Filament do it?
As Filament is based on Livewire, it creates a TemporaryUploadedFile
under the hood. We can create a temporary signed route for the preview, the same way Livewire does it with file uploads.
The code
I'll be leaving out a the table
and getPages
methods for the LinkResource.php
below. Have a look at the form
and the createTemporaryFileUploadFromUrl
methods to see how it works.
Using afterStateUpdated
we can dispatch a browser event using Livewire. This event will contain the temporary signed route url to the preview of the Favicon fetched with the Favicon Fetcher package.
With extraAlpineAttributes
on the FileUpload
field, we can listen to the event and instruct FilePond, the library used by Filament for upload fields, to upload the image.
This works with both, Filament upload fields and the official spatie media library plugin.
Video for this post
Please like and subscribe, if you found the video useful. As a new video creator, it helps a lot.