blalmal10a/free-upload
Free Upload is a Laravel package that simplifies file uploads by providing helpers for validation, storage, and retrieval, so you can add upload handling to your application with minimal configuration and less boilerplate.
Install and wire up
composer require blalmal10a/free-upload
php artisan vendor:publish # config + component stub tags
Confirm ext-gd is enabled (php -m | grep gd). The package requires PHP ^8.2 and Filament ^4.0|^5.0.
Look here first
config/free-upload.php — the five knobs that matter: upload_endpoint, proxy_base_url, image_path, files_path, proxy_timeout.routes/ (or the service provider) — three routes under a configurable prefix: POST /freeupload/upload, GET /freeupload/images/{id}/{filename}, GET /freeupload/files/{id}/{filename}.FreeUploadFileController + Proxy — the entire serving path is two small classes, so this is where you debug anything odd.PxvtDecoder — only relevant when you accept non-image files.First use case — drop the field into a Filament form. Because state is a plain URL string, it works against any existing string column:
use Blalmal10a\FreeUpload\Forms\Components\FreeUpload;
FreeUpload::make('avatar') // resolves to a URL string on your own domain
->image()
->directory('avatars'),
Upload a small image, confirm the stored value is https://yourapp.test/freeupload/images/{id}/{filename} (not an iili.io URL), and that the preview renders.
$wire.set(...) rather than Filament's FileUpload temporary-upload state, you can retrofit it onto existing models without a media table, spatie/laravel-medialibrary, or a disk abstraction. Treat the column as opaque and never parse the filename.upload_endpoint accepts a full URL, a path, or a route name. Use the route name (freeupload.upload) in normal apps so route:cache and host changes resolve automatically; use a full URL only when a separate frontend domain needs to POST cross-origin (you'll then own the CORS config).proxy_base_url is the stable public face. Set it once and leave it alone — see gotchas. Useful when you put a CDN or a subdomain in front of the app and don't want to rewrite stored records.auth/verified middleware plus a prefix. The proxy GETs are file-serving endpoints; unauthenticated is fine for public assets, but the POST /upload endpoint should almost certainly not be open.php artisan freeupload:publish-component (or vendor:publish --tag=free-upload-component) drops a stub with a namespace placeholder — replace that with your app namespace, then edit the view for progress-bar styling, accept lists, or extra metadata.proxy_base_url at http://localhost, and assert on the controller responses. The package's own 43-test Pest suite is a good template for Proxy/PxvtDecoder edge cases.FreeUploadFileController → Proxy → iili.io. There is no caching layer in the release notes. Put an HTTP cache in front (CDN, Cache::remember on the binary, or a response()->stream() with long Cache-Control) before this sees production traffic, or your app becomes the bottleneck for its own assets.proxy_timeout is your first knob when images hang. Default values will be too low for large files and too high for a dead upstream. Separate the upload timeout from the fetch timeout mentally — they're different failure modes.upload_max_filesize, post_max_size, max_execution_time, or memory limits in GD. PXVT-decoding a large encoded PNG is memory-hungry; set an explicit maxSize on the component.APP_URL or proxy_base_url orphans every existing record. Pick a canonical value on day one and prefer a relative-to-domain CDN host you'll never move.upload_endpoint is a route name, the route must exist at boot; renaming the prefix without updating config silently 404s the upload. Add a smoke test asserting a successful POST.FileUpload feature (multiple files, reordering, image editor, ->disk() semantics). Spot-check the specific affordances your form needs on both Filament v4 and v5 — the supported-version range spans two majors.FreeUploadFileController in a route override for storage/caching middleware, and keep Proxy/PxvtDecoder covered by your own tests since they're the parts most likely to break on an upstream change.How can I help you explore Laravel packages today?