--- type: video yt_id: VVU2YVRMdUlfajQtMHdpRFN6bWFQY3RRLnlHWWVZSnBSV1BN videoId: yGYeYJpRWPM title: "Upload Images Directly to S3 from Front End" date: "2021-04-08T14:30:05Z" slug: "upload-images-directly-to-s3-from-front-end" image: name: "upload-images-directly-to-s3-from-front-end.jpg" alt: "Upload Images Directly to S3 from Front End" width: 1280 height: 720 status: 'published' description: "Learn how to store your web app's image files in an s3 bucket by uploading them directly to the bucket." tags: ['JavaScript', 'js', 'aws', 's3', 'serverless'] previousPostSlug: 's3-bucket-hosting-a-static-website' nextPostSlug: 'uploading-images-express-and-react' --- Learn how to store your web app's image files in an s3 bucket by uploading them directly to the bucket. This technique is especially useful in serverless environemnts like when you're using lambda functions or a Next.js application. There is a different version of this tutorial that I suggest you check out too: ## Code: [https://github.com/Sam-Meech-Ward/s3-direct-upload](https://github.com/Sam-Meech-Ward/s3-direct-upload) ```js import express from 'express' import { generateUploadURL } from './s3.js' const app = express() app.use(express.static('front')) app.get('/s3Url', async (req, res) => { const url = await generateUploadURL() res.send({url}) }) app.listen(8080, () => console.log("listening on port 8080")) ``` ```js import dotenv from 'dotenv' import aws from 'aws-sdk' import crypto from 'crypto' import { promisify } from "util" const randomBytes = promisify(crypto.randomBytes) dotenv.config() const region = "us-west-2" const bucketName = "direct-upload-s3-bucket-thing" const accessKeyId = process.env.AWS_ACCESS_KEY_ID const secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY const s3 = new aws.S3({ region, accessKeyId, secretAccessKey, signatureVersion: 'v4' }) export async function generateUploadURL() { const rawBytes = await randomBytes(16) const imageName = rawBytes.toString('hex') const params = ({ Bucket: bucketName, Key: imageName, Expires: 60 }) const uploadURL = await s3.getSignedUrlPromise('putObject', params) return uploadURL } ``` ```js const imageForm = document.querySelector("#imageForm") const imageInput = document.querySelector("#imageInput") imageForm.addEventListener("submit", async event => { event.preventDefault() const file = imageInput.files[0] // get secure url from our server const { url } = await fetch("/s3Url").then(res => res.json()) console.log(url) // post the image direclty to the s3 bucket await fetch(url, { method: "PUT", headers: { "Content-Type": "multipart/form-data" }, body: file }) const imageUrl = url.split('?')[0] console.log(imageUrl) // post requst to my server to store any extra data const img = document.createElement("img") img.src = imageUrl document.body.appendChild(img) }) ```