Direct-to-S3: Mastering Serverless File Uploads in Laravel Vapor
The Serverless Upload Paradigm
In a traditional server environment, your local file system acts as a reliable, persistent closet. In the
Prerequisites & Toolkit
Before adjusting your code, ensure you are comfortable with
- Laravel Vapor JS SDK: A dedicated package providing helpers for signed S3 uploads.
- Axios: For communicating the file's final location to your Laravelbackend.
- AWS Console: To configure local development buckets and CORS settings.
Frontend Implementation with Vapor.store()
To start, install the laravel-vapor package via NPM and make it globally accessible in your app.js. The core logic lives in your Vapor.store() helper. This method generates a pre-signed URL and handles the heavy lifting of moving the binary data to S3. Once the upload finishes, it returns a unique key which you then send to your backend via
// Intercepting the submit event
$('#profileForm').on('submit', function(e) {
e.preventDefault();
const file = $('#image')[0].files[0];
Vapor.store(file).then(response => {
axios.post('/profile', {
key: response.key,
extension: response.extension
}).then(() => window.location.reload());
});
});
Backend Coordination and S3 Logic
Your backend route no longer receives a file; it receives a reference. In web.php, you must validate this key and move the file from its temporary location to its permanent path. Use the Storage::disk('s3') facade to manage these operations. This ensures your
// web.php route logic
$key = $request->input('key');
Storage::disk('s3')->copy($key, 'profiles/' . auth()->id() . '.jpg');
Critical Configuration: CORS and Permissions
Local development requires a manual UserPolicy includes an uploadFiles method returning true, or Vapor will block the signed URL generation. For public visibility, always specify the 'public' visibility flag when moving files to their final destination.
