Uploading Files to Amazon S3 in a Next.js Application Using AWS SDK v3
In this tutorial, we will walk through how to upload files to Amazon S3 in a Next.js application using the AWS SDK for JavaScript (v3). We will ensure that the files are served securely over HTTPS using the appropriate URL format.
Prerequisites
- Basic knowledge of Next.js
- An AWS account
- Node.js installed on your machine
Step 1: Set Up Your S3 Bucket
Create an S3 Bucket
- Go to the AWS Management Console.
- Navigate to the S3 service and create a new bucket.
- Choose a unique name and a region closest to your users.
- Set up the bucket to allow public read access for simplicity (you can refine the permissions later).
Set Bucket Policy and CORS
Bucket Policy
Add the following bucket policy to allow public read access:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::your-bucket-name/uploads/*"
}
]
}
CORS Configuration
Configure your bucket with the following CORS rules:
<CORSConfiguration>
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>HEAD</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>DELETE</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
Step 2: Set Up AWS SDK v3
Install AWS SDK v3
In your Next.js project, install the required AWS SDK packages:
npm install @aws-sdk/client-s3 @aws-sdk/lib-storage
Step 3: Create an API Route for File Upload
Create an API route in your Next.js application to handle file uploads to S3.
Create /src/app/api/upload/route.js
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';
import { Upload } from '@aws-sdk/lib-storage';
const s3Client = new S3Client({
region: process.env.AWS_REGION,
credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
},
});
export async function POST(req) {
try {
const { file } = await req.json();
const base64Data = Buffer.from(file.replace(/^data:image\/\w+;base64,/, ""), 'base64');
const type = file.split(';')[0].split('/')[1];
const params = {
Bucket: process.env.AWS_BUCKET_NAME,
Key: `uploads/${Date.now().toString()}.${type}`,
Body: base64Data,
ContentEncoding: 'base64',
ContentType: `image/${type}`,
};
const upload = new Upload({
client: s3Client,
params: params,
});
const data = await upload.done();
// Generate the URL in the desired format
const url = `https://s3.amazonaws.com/${params.Bucket}/${params.Key}`;
return new Response(JSON.stringify({ url: url }), {
status: 200,
headers: { 'Content-Type': 'application/json' },
});
} catch (error) {
return new Response(JSON.stringify({ error: error.message }), {
status: 500,
headers: { 'Content-Type': 'application/json' },
});
}
}
Step 4: Create a File Upload Component
Create a file upload component to allow users to upload files from the client-side.
Create /src/components/FileUpload.js
'use client';
import { useState } from 'react';
const FileUpload = () => {
const [file, setFile] = useState(null);
const [message, setMessage] = useState('');
const handleChange = (event) => {
setFile(event.target.files[0]);
};
const handleSubmit = async (event) => {
event.preventDefault();
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onloadend = async () => {
const base64data = reader.result;
const response = await fetch('/api/upload', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ file: base64data }),
});
if (response.ok) {
const data = await response.json();
setMessage(`File uploaded successfully! File URL: ${data.url}`);
} else {
setMessage('File upload failed.');
}
};
};
return (
<form onSubmit={handleSubmit}>
<input type="file" onChange={handleChange} />
<button type="submit">Upload</button>
{message && <p>{message}</p>}
</form>
);
};
export default FileUpload;
Step 5: Use the Component in Your Page
Include the FileUpload
component in one of your Next.js pages.
Create /src/app/page.js
import FileUpload from '../components/FileUpload';
export default function Home() {
return (
<div>
<h1>Upload a File to S3</h1>
<FileUpload />
</div>
);
}
Step 6: Configure Environment Variables
Ensure you have the necessary environment variables set up in your Next.js project. Create a .env.local
file in the root of your project if it doesn't exist:
Create .env.local
AWS_ACCESS_KEY_ID=your-access-key-id
AWS_SECRET_ACCESS_KEY=your-secret-access-key
AWS_REGION=your-region
AWS_BUCKET_NAME=your-bucket-name
Replace your-access-key-id
, your-secret-access-key
, your-region
, and your-bucket-name
with the actual values from your AWS account.
Step 7: Restart Your Development Server
Make sure to restart your Next.js development server to apply the new environment variables.
Conclusion
By following these steps, you should be able to upload files from your Next.js application to an S3 bucket using the AWS SDK for JavaScript (v3). The files will be served securely via HTTPS using the correct URL format. Happy coding!