Upload file to S3 with Laravel and Vue.js

May 26, 2019

In this tutorial I’m going to go through the process of uploading files to an AWS S3 bucket using Laravel, PHP and Vue.js. The goal is for approved candidates to upload their resume to Employbl.

Upload file to S3 with Laravel and Vue.js

If you are interested in joining Employbl as a candidate click here. For employer access to browse approved candidates click here.

About Employbl

Employbl is a talent marketplace. Candidates apply to join. I generally approve candidate applications if the candidate is authorized to work in the United States and has a background or clear interest in Software Engineering, Digital Marketing, Design or Product Management.

Companies are allowed to join Employbl and browse talent if they have a physical office in the Bay Area and recruit directly for positions they’re hiring for. Employbl isn’t built for third party or agency recruiters. If recruiters have a company email address for the company they’re recruiting for they’re good to go to start hiring from the Employbl network!

Resumes are the bread and butter recruiters use to evaluate candidates. In this post I’m going to add the ability for candidates to upload and feature their resume on their Employbl profile.

Step 1: Create the frontend form in Vue.js

The update profile information form is in a Vue.js component called ProfileForm.vue. That form sends an asynchronous POST request via the axios npm library. This is the first thing candidates see after they login to their account.

I’m adding a new HTML input field and Vue component method that allows users to upload their resume. Here’s the code to do that:

In this Vue.js component there’s HTML for uploading the file and rendering the file result if it exists. If the candidate has uploaded their resume already, show it. If the candidate uploads a file read and upload it to the Laravel backend.

Step 2: Create the File Upload endpoint in Laravel

The next step is to define our Laravel endpoint so that candidates can upload files to S3.

That endpoint looks like this in my routes/web.php file. It could easily live in the routes/api.php as well. I’m looking forward to studying through the Laravel, Vue and SPA course on Laracasts.

Route::post('/candidates/{user}/resume', 'CandidateController@uploadResume')->name('candidates.uploadResume');

In the app/Http/Controllers/CandidateController.php we’re going to check first that the candidate we’re uploading the resume for is the same as whoever has logged in. I store candidate information on the users table. Candidates that login should only be able to upload a resume for themselves!

Laravel has some amazing helper functions. I use the auth helper to check the authenticated user. There’s a helper for getting the request object and route model binding for injecting the user record based on id.

Getting the file from the request returns instance of Illuminate/Http/UploadedFile, which extends a Symphony component called SymfonyUploadedFile. That Symphony component provided the getClientOriginalExtension() method that I use for populating the file extension, like .pdf or .docx or .doc.

I use the Laravel Storage Facade (link to Laravel source code). You’ll see there’s no putFileAs method on the Storage class. This confused me until I read in the Laravel docs How Facades Work.

There’s a getFacadeAccessor method on the Stoage class that returns the name of the service container binding. The putFileAs method lives in the FileSystemAdapter.php class. Laravel source code for that class here.

Once we create an S3 bucket and let Laravel know about our AWS account credentials, this PHP code will upload and store a candidate’s resume!

Step 3: Configure AWS and Laravel

To upload files to S3 we’ll need to set up an S3 bucket and connect Laravel to our AWS account. S3 stands for Simple Storage Service and is one of the fundamental offerings of AWS.

Laravel offers connectivity with S3 more or less out of the box. The filesystem configuration and connection to S3 information lives in the config/filesystem.php file.

It’s best practice to store your AWS credentials in the .env located in the root of the project. Below are the environment variables we need:


Definitely take the time to read the Laravel filesystem docs. In there it lists a couple composer packages you’ll need to install.

It’s not best practice to use your root account credentials to connect to AWS. Instead, create a user through the AWS Identity Access Management (IAM) dashboard.

I created a user with my username and gave myself administrator access:

Create a new IAM user through the AWS console

Once the user is created use these values to populate the AWS_KEY and AWS_SECRET values. The bucket name and region we’ll populate after creating our S3 bucket for the filesystem.

Log into the AWS console and create a new S3 bucket.

Create a new Amazon S3 bucket on AWS

Once I created a new S3 bucket I added a folder in the bucket called “resumes”.

Update the AWS_BUCKET and AWS_REGION with the appropriate values.

For the AWS region, look at this list of AWS region shortcodes. In my case I selected “US West (N. California)” when creating the bucket. Then in my .env file I put AWS_REGION=us-west-1.

Step 4: Render file to Candidate Profile with Laravel Blade

I render the candidate profile for recruiters to see using Laravel Blade. Using Blade I conditionally render an iFrame if the candidate has uploaded a resume.

If they haven’t uploaded a resume express that.


That’s about it! If you have any questions or run into trouble hit me up on Twitter.

Feel free to apply to Employbl as a candidate click here. You can use Employbl to find job opportunities or startup and tech companies in the Bay Area.

Employers can browse approved candidates (and their resumes) after applying here. There are no hiring fees. I haven’t started charging employers for network access at all. It pays to be an early adopter!

Thanks for reading. If you enjoyed the post consider sharing with your friends or social network 💯

Let Bay Area companies find you

Join candidate network