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鈥檚 dive in! 馃強鈥嶁檪锔�/p>
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 馃洜锔�/p>
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
*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 });
}
}
*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>
);
}
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鈥檚 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 });
}
}
Wrapping Up 馃巵
And that鈥檚 it! You鈥檝e 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!
Let me know if this was helpful, and feel free to drop your thoughts or questions below. Happy coding! 馃捇鉁�/p>
Top comments (0)