Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Free Upload Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. 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.

  2. 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.
  3. 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.

Implementation Patterns

  • String-column storage is the win. Because the component writes URL strings through $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.
  • Endpoint flexibility for multi-tenant / multi-domain. 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.
  • Lock down the routes. Publish the config and add 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.
  • Customize via the published component, not a fork. 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.
  • Non-image handling. Images go up raw; PDFs/ZIPs get client-side PXVT-encoded into a PNG and decoded again in the proxy. This is clever for working around an image-only host, but treat it as a convenience path for small documents, not a general file store.
  • Testing. Http::fake the iili.io fetch, point 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.

Gotchas and Tips

  • The proxy is a PHP hot path. Every image render on every page hit goes through 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.
  • PHP limits still apply. Client-side progress bars do not bypass 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.
  • Stored URLs are absolute and point at your app. Changing 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.
  • Upstream dependency is real. The proxy fetches from iili.io and decodes PXVT; if that host changes its URL shape or response, uploads break with decoder errors that look like application bugs. Wrap the proxy call in a try/catch and log the upstream status code explicitly — the default failure is opaque.
  • Route-name endpoints break on config drift. If 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.
  • No deletion story in the notes. There's no mention of cleanup when a record is deleted or a file is replaced, and no cache-eviction route. Build an observer/job if orphaned upstream files matter to you.
  • Verify Filament parity before committing. The custom XHR component won't automatically inherit every 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.
  • Extension points: publish the component for UI, bind your own subclass of 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.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource