Using AWS S3 bucket on React for newbies
Tags: react, aws, s3
Published: 2021-01-06 00:49:34

I just learned how to use the AWS S3 bucket on React and it's a lot easier than I thought to set up! I just wanted to spend a few minutes to share what I learned.
First, you must set up an AWS account. Afterwards, go to the AWS console here: [AWS console](https://console.aws.amazon.com/iam/home?#home)
Second, make sure to create yourself an IAM user in order to access the account. After setting up the user, you need to create an access key and save the secret access key somewhere secret so you can use again. IMPORTANT NOTE! 1. Don't give out your secret access key! Keep it secret! 2. Make sure to save it because you will only see it one time. Here are some detailed instructions that I found helpful below:
[secret access key instructions](https://supsystic.com/documentation/id-secret-access-key-amazon-s3/)
After you have retrieved your access key ID and your secret access key, make sure to save it in a safe place. As a newbie, the only way I know how to keep my secrets safe is to store them in the environment variables. I created a file called .env.local (please make sure that it's called out in your .gitignore file). The prefix of your variable should be something like:
REACT_APP_AWS_ACCESS_ID_KEY=12345
REACT_APP_AWS_SECRET_KEY=123456
When loading your environment variables, you need to make sure to call on for example: process.env.REACT_APP_AWS_ACCESS_ID_KEY.
At some point you need to setup your S3 bucket where you want to keep your files, in your AWS console, search "S3" and it should take you to your S3 bucket. After that, create the bucket with the settings you choose. For my application, I made sure that I setup a CORS policy. If you have a domain name setup, this is where you would put the CORS policy to allow certain sites to work. Here is a link that helped me set that up:
[CORS for S3](https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html) 
My CORS policy looked something like this:
```
{
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "PUT",
            "POST",
            "DELETE"
        ],
        "AllowedOrigins": [
            "https://example.com"
        ],
        "ExposeHeaders": []
    }
```
Also, you may need to set a specific policy for creating access points for the S3 bucket that was created. Here is a link for more information:
[Creating access points for S3](https://docs.aws.amazon.com/AmazonS3/latest/dev/creating-access-points.html#access-points-bpa-settings)
Every developer should determine how they want to setup their access points or how they should 
If you follow all of these steps, you should be ready to start setting up your React app
After that, in your React app directory, run:
```
npm i react-s3
```
Here is the link to the documentation: [react-s3](https://www.npmjs.com/package/react-s3)

In your React application, you should create a config object like the one shown below

```javascript
const config = {
    bucketName: 'yourbucketname',
    dirName: 'yourdirectoryname', //optional
    region: 'us-east-1',
    accessKeyId: 'your access key id',
    secretAccessKey: 'your super secret access key'
}
```
After this is defined somewhere and possibly imported if you need, here is the code that I used for uploading:

```javascript
import { Form } from "react-bootstrap"
import FormFileInput from "react-bootstrap/esm/FormFileInput"
import S3FileUpload from 'react-s3'
import imageCompression from 'browser-image-compression'

const config = {
    //your configuration as shown above
}

export const UploadFile = (props) => {


    const handleUpload = (event) => {
        
        const imageFile = event.target.files[0];
        console.log('originalFile instanceof Blob', imageFile instanceof Blob); // true
        console.log(`originalFile size ${imageFile.size / 1024 / 1024} MB`);
        
        const options = {
            maxSizeMB: 1,
            maxWidthOrHeight: 300,
            useWebWorker: true
        }
        try {
            const compressedFile = await imageCompression(imageFile, options);
            console.log('compressedFile instanceof Blob', compressedFile instanceof Blob); // true
            console.log(`compressedFile size ${compressedFile.size / 1024 / 1024} MB`); // smaller than maxSizeMB
        
            S3FileUpload.uploadFile(compressedFile, config)
                .then(data => console.log(data))
                .catch(err => console.error(err)) // write your own logic
        } catch (error) {
            console.log(error);
        }

        
    }

    return (
        <Form >
            <FormFileInput onChange={handleUpload}></FormFileInput>
        </Form>
    )
}
```
I used react-bootstrap to put together the form; however, you won't need to do so for your testing purposes. Also, I thought it might be necessary to compress the images that way the web page loads faster.
So just to summarize the actual part where we do the upload is:

```javascript
S3FileUpload.uploadFile(compressedFile, config)
                .then(data => console.log(data))
                .catch(err => console.error(err)) // write your own logic
```
I am planning to use the data.location(the image url) to insert into my database. After that, you should be good to go!
Happy coding!