Direct-to-S3: Mastering Serverless File Uploads in Laravel Vapor

Laravel////3 min read

The Serverless Upload Paradigm

In a traditional server environment, your local file system acts as a reliable, persistent closet. In the serverless world of Laravel Vapor, that closet is temporary and liable to vanish at any moment. When a Lambda function handles a file upload directly, you risk hitting API Gateway payload limits—typically capped at 10MB—and losing data when the container terminates. To build robust applications, you must bypass the backend and upload files directly from the client to AWS S3.

Prerequisites & Toolkit

Before adjusting your code, ensure you are comfortable with Laravel basics and JavaScript event handling. You will need:

  • Laravel Vapor JS SDK: A dedicated package providing helpers for signed S3 uploads.
  • Axios: For communicating the file's final location to your Laravel backend.
  • 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 Blade view, where you must intercept the form submission. Instead of a standard POST request, use the 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 Axios.

// 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 Lambda function remains stateless and lightweight.

// 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 AWS S3 bucket. You must edit the CORS (Cross-Origin Resource Sharing) configuration in the AWS Management Console to allow your local domain to perform PUT requests. Additionally, ensure your 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.

Topic DensityMention share of the most discussed topics · 13 mentions across 10 distinct topics
AWS S3
15%· technology
Lambda
15%· technology
Laravel
15%· technology
API Gateway
8%· technology
AWS Management Console
8%· technology
Other topics
38%
End of Article
Source video
Direct-to-S3: Mastering Serverless File Uploads in Laravel Vapor

Learn Laravel Vapor #20: File Uploads

Watch

Laravel // 15:54

The official YouTube channel of Laravel, the clean stack for Artisans and agents. We will update you on what's new in the world of Laravel, from the framework to our products Cloud, Forge, and Nightwatch.

3 min read0%
3 min read