owainjones74/filament-file-upload-chunked
A Filament plugin for chunked file uploads that splits large files into smaller pieces for more reliable uploads and helps work around PHP upload limits. Integrates with Filament forms for smoother large-file handling.
Install the package and publish any assets/config it ships with:
composer require owainjones74/filament-file-upload-chunked
php artisan vendor:publish --tag="filament-file-upload-chunked-config"
php artisan filament:assets
php artisan optimize:clear
Look first at:
config/filament-chunked-file-upload-chunked.php or the published config file, if present, for chunk size, temp paths, and disk defaults.src/Forms/Components/ChunkedFileUpload.php in vendor/owainjones74/filament-file-upload-chunked to confirm which Filament FileUpload methods it supports.The first practical use case is replacing a normal Filament FileUpload field for large PDFs, videos, or archives where PHP/Livewire limits otherwise cause failed uploads:
use OwainJones\FilamentChunkedFileUploads\Forms\Components\ChunkedFileUpload;
ChunkedFileUpload::make('attachment')
->disk('local')
->directory('attachments')
->acceptedFileTypes(['application/pdf', 'video/mp4'])
->maxSize(500 * 1024) // Filament maxSize is usually KB
->chunkSize(5 * 1024 * 1024); // confirm units in README; often bytes
Start by swapping one large-file field, verify the browser sends multiple chunk requests in the network tab, and confirm the assembled file lands on the expected disk/path. Keep normal FileUpload for small images and avatars.
Use chunked uploads selectively. Keep Filament’s standard FileUpload for images, thumbnails, and small documents. Use ChunkedFileUpload only where file size is the problem; chunking adds request volume and temp-file cleanup concerns.
Configure disk and directory explicitly. Do not rely on global defaults for important uploads:
ChunkedFileUpload::make('contract')
->disk('private')
->directory(fn () => 'tenants/' . auth()->user()->tenant_id . '/contracts')
->visibility('private')
->acceptedFileTypes(['application/pdf'])
->maxSize(200 * 1024)
->chunkSize(5 * 1024 * 1024);
For tenant-aware apps, derive the directory from the authenticated user/tenant server-side. Do not accept a client-provided directory.
Pair client validation with server rules. Use acceptedFileTypes() and maxSize() for UI feedback, but keep model/policy validation and a final file check in your save action or job. MIME detection can differ between browser and server, especially for large media files.
Treat the upload as a staging step. Store the final path on your model, then dispatch post-processing to a queue:
->afterStateUpdated(function ($state) {
// Avoid heavy work here; Livewire requests can time out.
})
For example, after saving the form, dispatch a job to generate thumbnails, virus-scan, or move the file to permanent storage. This keeps the Livewire upload request short.
Use chunk size as a tuning knob. A 5 MB chunk is a reasonable default. Very small chunks create hundreds of requests and slow uploads; very large chunks hit PHP/nginx limits and reduce retry granularity. Align chunk size with:
upload_max_filesizepost_max_sizeclient_max_body_sizeHandle progress and retries in the UI. Chunked uploads are network-sensitive. Add helper text explaining that large files upload in parts, and test on slow connections. If the package exposes upload progress events, use them to disable submit while chunks are in flight.
Test with browser coverage. Livewire unit tests will not exercise the JavaScript chunking loop. Use Storage::fake() and a small fake file for form/component tests, then use a browser test or manual network-tab check to verify actual chunking, retries, and final assembly.
maxSize() is typically in kilobytes, while chunk-size options in upload packages are often in bytes. Confirm both in the README before setting values.php artisan filament:assets, clear config/cache, and confirm the package service provider is auto-discovered or registered.client_max_body_size, timeouts, and buffering settings. Long uploads can also outlive sessions; consider session lifetime and re-auth behavior.->multiple() support before using it for galleries or bulk imports. Chunked multiple uploads can create many concurrent requests and complicate progress UI.storage/logs/laravel.log for assembly errors, inspect the configured temp directory for leftover chunks, and verify the final path with Storage::disk(...)->exists(...).ChunkedFileUpload extends Filament’s FileUpload, standard callbacks such as saveUploadedFileUsing() may work, but confirm in the source before depending on them. For anything non-trivial, wrap the upload in your own form action/service class rather than fighting the component.How can I help you explore Laravel packages today?