Without the struggle with CORS policy.
NextJS is a frontend framework, and since the frontend doesn’t have an access to the different origins due to the CORS policy, it’s tedious to implement it if you’re doing it in the wrong way. Of course that you can alter going out requests in the next.config.js file with redirection from an API route, but then using NextJS serverless API which is super handy, lose its benefits. In this “fast, to the point” article we’re gonna go over the steps needed in order to make it work.
Btw if you prefer to work with ready code, you can find such here:
If you don’t know what AWS S3 is, S3 stands for Simple Storage Service and it’s exactly that. It allows you to store all of the different files online on Amazon servers, and retrieve them fast and safely. An additional bonus is the “pay as you scale” business model, which let you try the service out, even use it in production for free if you’re needs aren’t that big. With that said, let’s now focus on what we have to do in order to use it in our web app.
1. Create an AWS account
You can sign in to the console there. The difference between a root user and an IAM user is, that a root user’s credentials are the credentials through which you’ve registered, providing your card and billing details. IAM user accounts are the ones, which you create for individual AWS services. Summing it up, you want to create a root user there.
2. Navigate to the S3/IAM service
If it’s your first time using AWS, don’t worry, it’s intuitive. Basically, you have an access to all of the services from one account, and you search for them either from the recently visited services section or the search bar. In the case of this tutorial, we’ll need just two services — S3 which will provide us with storage capabilities, and IAM where we’ll create access policies.
1. Creating a bucket
The first thing which we’ll gonna configure is S3. As you can see in the below image S3 works on “Buckets” philosophy. You create a bucket in which you’ll store your files.
While creating a bucket you’d probably like to leave almost everything as it is, with an exception to the “block all public access” option. Since we want to allow a public upload from our users, we’ll live it empty.
2. Bucket properties configuration
Bucket Policy — are responsible for managing access. For the sake of simplicity, we’re gonna set it to the public so we can access the resource afterward without any unnecessary authentication. The configuration is pretty standard. Just remember to insert your bucket name in the place of
YOUR_BUCKET_NAME_HERE if you’re copy-pasting it (of course you are, we’re all programmers).
CORS — Cors properties also can be set from within the permissions tab. Feel free to copy-paste my configuration, which as you can see is nothing crazy. We basically allow all of the origins to access our bucket.
IAM aka API Key
Since we’re gonna connect with Amazon we need some sort of authentication. We can do it from the IAM section. As you can see I already have one user group created
Click create group, and you’ll be able to choose appropriate rights. Simply go with AmazonS3FullAccess.
Afterward, you should see a group that you’ve just created in your panel.
Then we want to create a User to which we’ll assign an access group created a second ago.
Choose programmatic access since we want to elevate AWS SDK using an API, and for this purpose, we’ll need API credentials. After successful user creation, you’ll be able to fetch its Access key ID and secret access key. You want to grab those, and we will make use of them in the next section related to Next JS.
Phew, we have the least intersting work done (I’m sorry AWS admins, it’s just my personal opinion). Now we can answer the question about how we can upload files using a frontend framework.
So how will we approach this problem? We will create an API route, which will create signedUrl for us, to which we then gonna make a PUT request passing the file; we want to upload as a body. If it sounds complicated just go through the code, it will have much more sense in a minute.
1. Installing NextJS along with Tailwind CSS and Typescript
I don’t know about you, but my preferred way of working with NextJS is to do it with Typescript and Tailwind CSS. Typescript gives me type checks, and tailwind allows me to write CSS super-fast, almost like on the steroids. To save yourself a hassle in setting it up, here is a template with preconfigured Typescript and Tailwind which you can use:
2. Install necessary libraries
For this to work we just need two libraries:
axios: which allow us to make HTTP requests,
aws-sdk: which allow us to make use of AWS services
3. Create file input
The following code creates just a simple input of type file, which allow us to fetch a file we’ve inputted in.
Let’s just store it in
4. Store your API keys from an AWS in .env.local file
Remember as I told you that there’s no really something like safe stored environmental variables in frontend? I’ve meant that. But since Next JS API is serverless and it’s our backend we can safely make use of them here. Any environmental variables which are not prefixed with
NEXT_PUBLIC_ won’t be exposed to the browser. In .env.local file create three variables
SECRET_KEYand bucket name:
5. Set up an S3 instance and config properties
First things first. You have to import S3 and create a new instance of it. As you can see properties are pretty self-explanatory, you have to specify a region, pass an access key and secret key, and signature version which we’ll set to v4. In NextJS if you would like to specify any different than default body-parsing properties you can do it in the config variable which you have to export. We’re setting a maximum uploaded file size to 8mb.
6. Create an API route logic
First, we exclude any other HTTP method than POST, then we create file params needed for s3 to generate a signedUrl for us. As you can see there are some options needed. In the POST body, we send a name and the type of file, which we want to upload. We also set the “expires” time to 600 seconds, and ACL for the “public-read” which will make this asset publicly accessible.
7. Uploading a File to AWS S3 bucket
Protip: if you’ve added your .env variables after starting up an app with yarn dev, remember to restart it, because env variables are fetched at the start of an application.
We first make use of the previously created
uploadFile endpoint, to which we send the name and type of a picked file. Then we fetch the URL which will allow us to upload a file to the AWS. The URL looks like in the screenshot below. Afterward, we send a PUT request with the file to the received URL.
In the URL the part till “.com/” is your bucket URL. You can copy it and store it somewhere if you want to access it later.
8. See the uploaded file in your bucket
Now you should see your freshly added file in the bucket. We’re done here.
If you would like to display an image in the HTML you can do it like that
In this article, you’ve learned how to create an AWS account, and how to create an S3 bucket along with IAM users. Now you’re also capable of NextJS app creation which will provide the functionality of uploading files to your bucket, and displaying results.
If you want to grab a code, it’s available here: