How to Upload Images and Videos to Amazon S3 with Next.js and AWS SDK v3?

How to Upload Images and Videos to Amazon S3 with Next.js and AWS SDK v3?

Published 19th, April, 2023

4 min read

In this comprehensive technical blog post, we will guide you through the process of uploading objects, specifically images and videos, to Amazon S3 using Next.js as the frontend framework and the AWS SDK for JavaScript v3. Next.js is a powerful React-based framework that simplifies the development of server-rendered applications, providing features like hybrid static and server rendering, TypeScript support, smart bundling, route pre-fetching, and more. On the other hand, Amazon S3 (Simple Storage Service) is an object storage service that offers industry-leading scalability, data availability, security, and performance.

By following this step-by-step guide, you will learn how to integrate Amazon S3 into your Next.js application, allowing users to upload and manage their media files seamlessly. This tutorial will not only help you understand the basics of Next.js and Amazon S3 integration but also give you the confidence to explore more advanced use cases and optimisations in the future.

Prerequisites:

  1. Basic knowledge of JavaScript, React, and Next.js.
  2. An AWS account with access to Amazon S3.
  3. Node.js (v16.0.0 or later) and npm (v7.0.0 or later) installed on your local machine.

Set up a Next.js project

First, create a new Next.js project using the following command:

npx create-next-app s3-upload-example

Navigate to the newly created project directory:

cd s3-upload-example

Install the AWS SDK for JavaScript v3 and other necessary packages using the following command:

npm install @aws-sdk/client-s3 @aws-sdk/s3-request-presigner next-connect multer

Create a .env.local file in the root of your project and add the following AWS credentials:

AWS_ACCESS_KEY_ID=your_access_key_id
AWS_SECRET_ACCESS_KEY=your_secret_access_key
AWS_REGION=your_aws_region
S3_BUCKET_NAME=your_s3_bucket_name

Replace the placeholders with your actual AWS credentials and S3 bucket information.

Set up the API route

Create a new folder named api inside the pages folder, and then create a new file named upload.js inside the api folder. Add the following code to upload.js:

import nextConnect from 'next-connect';
import multer from 'multer';
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';
import { createRequestPresigner } from '@aws-sdk/s3-request-presigner';

const s3 = new S3Client({
  region: process.env.AWS_REGION,
  credentials: {
    accessKeyId: process.env.AWS_ACCESS_KEY_ID,
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
  },
});

const upload = multer();

const handler = nextConnect()
  .use(upload.single('file'))
  .post(async (req, res) => {
    const file = req.file;
    const key = Date.now().toString() + '-' + file.originalname;

    const putParams = {
      Bucket: process.env.S3_BUCKET_NAME,
      Key: key,
      Body: file.buffer,
      ContentType: file.mimetype,
      ACL: 'public-read',
    };

    try {
      await s3.send(new PutObjectCommand(putParams));

      const signedUrl = await createRequestPresigner(s3);
      const url = signedUrl(putParams, { expiresIn: 60 * 60 * 1000 }); // 1 hour

      res.status(200).json({ url });
    } catch (error) {
      console.error(error);
      res.status(500).json({ error: 'Error uploading file to S3' });
    }
  });

export default handler;

This code sets up an API route that handles file uploads to Amazon S3 using the AWS SDK for JavaScript v3 and the multer middleware.

Implement the frontend file uploader

Create a new file named uploader.js in the components folder and add the following code:

import { useState } from 'react';

const Uploader = () => {
  const [file, setFile] = useState(null);
  const [uploading, setUploading] = useState(false);
  const [uploadUrl, setUploadUrl] = useState(null);

  const handleFileChange = (e) => {
    setFile(e.target.files[0]);
  };

  const handleSubmit = async (e) => {
    e.preventDefault();
    if (!file) return;

    setUploading(true);

    const formData = new FormData();
    formData.append('file', file);

    try {
      const response = await fetch('/api/upload', {
        method: 'POST',
        body: formData,
      });

      const data = await response.json();

      setUploadUrl(data.url);
      setUploading(false);
    } catch (error) {
      console.error('Error uploading file:', error);
      setUploading(false);
    }
  };

  return (
    <div>
      <h2>Upload Images and Videos to Amazon S3</h2>
      <form onSubmit={handleSubmit}>
        <input type="file" accept="image/*,video/*" onChange={handleFileChange} />
        <button type="submit" disabled={!file || uploading}>
          {uploading ? 'Uploading...' : 'Upload'}
        </button>
      </form>
      {uploadUrl && <p>File uploaded successfully! <a href={uploadUrl} target="_blank" rel="noopener noreferrer">View File</a></p>}
    </div>
  );
};

export default Uploader;

This component handles the file input, form submission, and interaction with the API route.

Add the uploader component to a page

Open the pages/index.js file and replace its content with the following code:

import Head from 'next/head';
import Uploader from '../components/uploader';

export default function Home() {
  return (
    <div>
      <Head>
        <title>Next.js S3 Upload Example</title>
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main>
        <Uploader />
      </main>
    </div>
  );
}

This code includes the Uploader component in the main page of the application.

Test your application

Run your Next.js application using the following command:

npm run dev

Navigate to http://localhost:3000 in your browser and test the file uploader. You should now be able to upload images and videos to your Amazon S3 bucket.

Conclusion:

In this tutorial, we have demonstrated how to upload images and videos to Amazon S3 using Next.js and the AWS SDK for JavaScript v3. This step-by-step guide should provide a solid foundation for integrating Amazon S3 into your Next.js applications, allowing users to seamlessly manage their media files.

Now that you have learned the basics, you can explore more advanced use cases and optimisations for your project. Some next steps you can consider are:

  1. Implementing user authentication and authorisation to manage access to uploaded files.
  2. Adding support for resizing images and transcoding videos on-the-fly using AWS Lambda.
  3. Enhancing the user experience by adding features like progress bars and drag-and-drop file uploads.
  4. Implementing a Content Delivery Network (CDN) like Amazon CloudFront to optimize file delivery to users worldwide.

With the skills acquired in this tutorial, you are now better equipped to create powerful and scalable web applications with Next.js and Amazon S3. Keep exploring and building amazing projects!

We specialises in custom software development.
Weโ€˜re happy to help with your requirements.

Web or mobile app development, database design and management, or any other software project, we can help you achieve your goals. Please contact us to discuss your project and receive a quote and timeline.