Next.js Single Image/Multiple Image upload to AWS s3

Atihar Hossen Mahir
3 min readMar 17, 2022

--

Objective: Uploading Single Image or multiple Image using next.js.

I was searching for uploading single image and multiple image from nextjs application to amazon s3 bucket.

You need to setup a public bucket. I will write a post about how to setup or there are many posts about it.

I am diving into nextjs part.

First we need ‘aws-sdk’ in our application

npm -i aws-sdk or npm install aws-sdk

Create separate api for the upload (my preference)

Disclaimer — When uploading files to s3 directly from front end, your AWS credentials are exposed in the network tab. Refrain from uploading files to protected S3 buckets directly from FE. Always use a server to upload files

// pages/api/upload-url.js

import aws from ‘aws-sdk’;

export default async function handler(req, res) {

aws.config.update({

accessKeyId: process.env.ACCESS_KEY,

secretAccessKey: process.env.SECRET_KEY,

region: process.env.REGION,

signatureVersion: ‘v4’,

});

const s3 = new aws.S3();

const post = await s3.createPresignedPost({

Bucket: process.env.BUCKET_NAME,

Fields: {

key: req.query.file,

},

Expires: 60, // seconds

Conditions: [

[‘content-length-range’, 0, 1048576], // up to 1 MB

],

});

res.status(200).json(post);

console.log(res)

}

For single Image Upload

//pages/single-image-upload.js

export default function Upload() {

const uploadPhoto = async (e) => {

const file = e.target.files[0];

const filename = encodeURIComponent(file.name);

const res = await fetch(`/api/upload-url?file=${filename}`);

const { url, fields } = await res.json();

const formData = new FormData();

Object.entries({ …fields, file }).forEach(([key, value]) => { formData.append(key, value); });

const upload = await fetch(url, { method: ‘POST’, body: formData, });

if (upload.ok) {

console.log(‘Uploaded successfully!’);

} else {

console.error(‘Upload failed.’);

} };

return (

<>

<p>Upload a .png or .jpg image (max 1MB).</p>

<input onChange={uploadPhoto} type=”file” accept=”image/png, image/jpeg” /> </>

);

}

multiple image upload

Note: I searched through many posts and videos.. Finally I found AWS don’t support multiple file over a single http request. So We will loop through the single process. Important.. You need to change the fileList to Array to loop through the multiple files

import { useState } from “react”;

export default function Upload() {

const [url, setUrl]= useState([]);

const uploadPhoto = async (e) => {

try{

const myFileList = e.target.files;

const newArr = […myFileList]

const v = await Promise.all(

newArr.map(async (file) => {

const filename = encodeURIComponent(file.name);

const res = await fetch(`/api/upload-url?file=${filename}`);

const { url, fields } = await res.json();

const formData = new FormData();

Object.entries({ …fields, file }).forEach(([key, value]) => {

formData.append(key, value);

});

const upload = await fetch(url, {

method: ‘POST’,

body: formData,

});

if (upload.ok) {

console.log(‘Uploaded successfully!’);

} else {

console.error(‘Upload failed.’);

}

})

)

} catch(e){

console.error(e)

}}

return (

<>

<p>Upload a .png or .jpg image (max 1MB).</p>

<input

onChange={uploadPhoto} type=”file”

accept=”image/png, image/jpeg”

multiple />

//your image will be here after upload. You can use state or map the array after response to show here.

<img src={“”}/>

</>

);}

Reference: AWS SDK for JavaScript 3

https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/s3-example-photo-album.html

--

--

Atihar Hossen Mahir
Atihar Hossen Mahir

Written by Atihar Hossen Mahir

Founder, Tech Product Development Leader | Advanced AI-Based Automation Enthusiast

No responses yet