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
*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β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 });
}
}
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!
Let me know if this was helpful, and feel free to drop your thoughts or questions below. Happy coding! π»β¨
Top comments (0)