DEV Community

Cover image for Upload to S3
Shubhainder Singh
Shubhainder Singh

Posted on

Upload to S3

Hello Devs! πŸ‘‹

nextjs + aws s3 + clerk auth

If you've ever wanted to integrate file uploads directly into your Next.js app, this post is for you! We'll walk through how to upload files to AWS S3 using the AWS SDK. Whether you're building an image gallery, document manager, or any app that deals with file storage, S3 is a great choice.

Let’s dive in! πŸŠβ€β™‚οΈ

Why S3? πŸ€”
Amazon S3 (Simple Storage Service) is a scalable, durable, and secure file storage solution. It's great for:

Storing user uploads (images, PDFs, etc.)
Backing up important data
Serving static assets (like images or videos)

Setting Up Your Project πŸ› οΈ

Prerequisites

Make sure you have:

A Next.js app
An AWS account
AWS credentials with permissions to access S3 (comment if you need a
post on how to access S3)

Install AWS SDK

First, install the AWS SDK in your project:

npm install @aws-sdk/client-s3
Enter fullscreen mode Exit fullscreen mode

*Backend Setup: API Routes for Uploading Files *πŸ“‘

File: app/api/upload/route.ts

This API route will handle file uploads.

import { NextRequest, NextResponse } from 'next/server';
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';

const s3Client = new S3Client({ region: process.env.AWS_S3_REGION });

export async function POST(request: NextRequest) {
  try {
    const formData = await request.formData();
    const file = formData.get('file') as File;

    if (!file) {
      return NextResponse.json({ error: 'No file uploaded' }, { status: 400 });
    }

    const bytes = await file.arrayBuffer();
    const buffer = Buffer.from(bytes);

    const uploadParams = {
      Bucket: process.env.AWS_S3_BUCKET_NAME!,
      Key: `uploads/${Date.now()}-${file.name}`,
      Body: buffer,
      ContentType: file.type,
    };

    await s3Client.send(new PutObjectCommand(uploadParams));

    return NextResponse.json({ success: true });
  } catch (error) {
    return NextResponse.json({ error: 'Upload failed', details: error }, { status: 500 });
  }
}
Enter fullscreen mode Exit fullscreen mode

*Frontend Setup: File Upload UI *πŸ“€

Create a simple upload form in your Next.js app.

File: components/Upload.tsx

import { useState } from 'react';

export default function Upload() {
  const [file, setFile] = useState<File | null>(null);
  const [message, setMessage] = useState('');

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

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

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

    if (res.ok) {
      setMessage('File uploaded successfully!');
    } else {
      setMessage('Failed to upload file.');
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <input type="file" onChange={(e) => setFile(e.target.files?.[0] || null)} />
      <button type="submit">Upload</button>
      {message && <p>{message}</p>}
    </form>
  );
}
Enter fullscreen mode Exit fullscreen mode

Testing Your Setup πŸ§ͺ
Start your Next.js app:

npm run dev

Navigate to your upload form.
Select a file and hit Upload.
Head over to your S3 bucket and confirm the file is there!

Bonus: Listing Files from S3 πŸ“œ
Want to display uploaded files? Here’s how:

File: app/api/files/route.ts

import { S3Client, ListObjectsV2Command } from '@aws-sdk/client-s3';
import { NextResponse } from 'next/server';

const s3Client = new S3Client({ region: process.env.AWS_S3_REGION });

export async function GET() {
  try {
    const command = new ListObjectsV2Command({
      Bucket: process.env.AWS_S3_BUCKET_NAME!,
    });

    const response = await s3Client.send(command);
    const files = response.Contents?.map((file) => ({
      name: file.Key,
      size: file.Size,
      lastModified: file.LastModified,
    }));

    return NextResponse.json({ files });
  } catch (error) {
    return NextResponse.json({ error: 'Failed to fetch files' }, { status: 500 });
  }
}
Enter fullscreen mode Exit fullscreen mode

Wrapping Up 🎁
And that’s it! You’ve now integrated file uploads to S3 in your Next.js app. This setup is production-ready, scalable, and easy to extend. Do you have ideas for improvements? Fork the project and share your contributions!

Github repository

Let me know if this was helpful, and feel free to drop your thoughts or questions below. Happy coding! πŸ’»βœ¨

Top comments (0)